0

I have a page in which I want to find all datetime values.

I want to find all datetime values and convert them from Hijri datetimes to standard datetimes.

How can I find datetime value with javascript and change it?

For example:

I want this code in html

<td class="ms-vb2"><nobr>18/02/1391 14:07</nobr></td>

I want to find the datetime value (18/02/1391 14:07), then change it to (14/08/2012 10:15) with javascript.

Edit

I use this code and find all date value

var re =  /[0-3]\d\/[01]\d\/\d{4}/g;
var dates = $("body").text().match(re);

How to replace it to new date???

ar.gorgin
  • 4,765
  • 12
  • 61
  • 100

3 Answers3

0

Due to the way that the DOM works, I would recommend wrapping your datetime value in a specific tag (with, perhaps, a specific class name). So instead of <nobr>08/02/1391 14:07</nobr>, you could have <span class="datetime">8/02/1391 14:07</span>. This would make finding your date easier, as you could use the DOM to identify tags with datetimes.

You could use jQuery's selectors to get the value....

$('.datetime').html()

...or you could use vanilla Javascript.

document.getElementsByClassName('datetime')

This is the first step in finding all of your datetimes. After that, for each datetime, you'll need to convert it into a usable format by calling the split() function, which should split a string into an array based on a delimiter. The default delimiter is a space, so you may have to repeat this to remove the slashes. So for jQuery, you'd have...

var mydate = $('.datetime').html()
var mydateArray = mydate.split(); // This doesn't deal with nested elements, since it's an example.

...while in vanilla Javascript (javanillascript???) you'd have:

var mydate = document.getElementsByClassName('datetime')
var mydateArray = mydate.split(); // This doesn't deal with nested elements, since it's an example.

After you have split your datetime string into usable chunks, you'll need to apply the math to all of those chunks. This is the most complicated part of this solution.

However, once you've calculated your dates and reformatted them for display, you can simply set them in your HTML. In jQuery:

var myNewDate = convertHijriToStandard(date);
$('.datetime').html(myNewDate);

Note that I would recommend using jQuery for this if you're looking for maximum browser support. Your date conversion may not use jQuery, but dealing with DOM elements may be much easier if you're supporting older browsers.

Best of luck. I know this isn't a complete solution, but hopefully it should get you started. Let me know if you have any questions.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
0

Looking at http://www.regular-expressions.info/dates.html we can do this to find all dates from 1300 to and including 1400:

var reg = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](13|14)\d\d$/g

so you you can do

var dates = document.body.innerHTML.match(reg);

but how to convert from this: http://en.wikipedia.org/wiki/List_of_Islamic_years#Modern I will leave up to a Talmudic scholar

The reg is not perfect - seems someone needs to make it work better. If it works you could do this in jQuery (DEMO)

var reg = /(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](13|14)\d\d \d\d:\d\d/g;
$(function() {
  var dates = $("body").text().match(reg);
  console.log(dates);  
  $.each(dates,function(date) {
      console.log(date);
      $("td:contains("+date+")").each(function() {
          $(this).text($(this).text().replace(date,"new date"));
      });
  });
});
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Close, but much better to iterate over all the text nodes. Using a regular expression and replacing the innerHTML will destroy all listeners other than those that are inline. – RobG Aug 25 '12 at 08:34
  • i use your code and find all date value, but how to replace value with new value?... my problem is: the value not in td tag. – ar.gorgin Aug 26 '12 at 04:30
  • Are you asking how to convert or what? – mplungjan Aug 26 '12 at 04:34
0

You are recurse over all text nodes starting from a particular element using the following (uses mplungjan's a simple regular expression):

// Recursively replace text in text nodes of elements
function replaceText(el) {

  var node, nodes = el.childNodes;
  var re = /[0-3]\d\/[01]\d\/\d{4} [012]\d:[012]\d/g;
  var t;

  for (var i=0, iLen=nodes.length; i < iLen; i++) {
    node = nodes[i];

    // Replace content of text nodes
    if (node.nodeType == 3) {
      t = node.data.match(re);

      // See if has a date
      if (t) {

        // Iterate over members of t, replacing Hijri dates with Gregorian dates
        // convertDate should be a function to do the conversion
        for (var j=0, jLen=t.length; j<jLen; j++) {
          node.data = node.data.replace(t[j], convertDate(t[j])); 
        }
      }

    // Recurse over elements to get at child text nodes
    } else if (node.childNodes) {
      replaceText(node);
    }
  }
}

If the intention is to do the entire document, pass it the body element.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • And this will be faster than doing innerHTML which also will handle title="12-01-1345" ? – mplungjan Aug 25 '12 at 08:53
  • No, but that isn't the point. As commented, an innerHTML method will destroy all dynamic listeners and may have other consequences. The difference in speed is likely irrelevant or unnoticeable. The title element can be handled by passing the HTML element to the function, or calling the function twice: once for the body and once for head or title. If using the HTML or head elements, it may be useful to skip script and style elements. – RobG Aug 25 '12 at 09:28
  • 1
    Cool, but what would the performance be like? Probably irrelevant for a few dates, let's hope there aren't hundreds! :-) Last time I looked, jQuery's *text* method iterates over text nodes per my answer, it should be very much faster to use *textContent* or *innerText* (as appropriate) to get the initial matches (just checked, it uses innerText and textContent too so must have decided "normalising" the result was pointless). – RobG Aug 27 '12 at 03:57