0

In my system, time stamps are returned using the old IBM julian format.

For example:
12 o'clock 0 minutes and 1 seconds AM (1 sec after midnight) is returned 01.
12 o'clock 22 minutes and 15 seconds AM is returned 2215.
1 o'clock 22 minutes and 15 seconds AM is returned 12215.
7 o'clock 45 minutes and 1 seconds AM is returned 74501.
7 o'clock 22 minutes and 15 seconds PM is returned 192215.

I need a regex expression to put these into the format of:
12 o'clock 0 minutes and 1 seconds AM (1 sec after midnight): 00:00.01
12 o'clock 22 minutes and 15 seconds AM: 00:22.15
1 o'clock 22 minutes and 15 seconds AM: 01:22.15
7 o'clock 45 minutes and 1 seconds AM: 7:45.01
7 o'clock 22 minutes and 15 seconds PM: 19:22.15

Any help is appreciated.

SOLUTION Thanks to MikeM, here is the solution:

//var time = '01';
//var time = '2215';
//var time = '12215';
//var time = '74501';
var time = '192215';

time = time.replace( /^(?:(?:(\d)?(\d))?(\d\d))?(\d\d)$/,
  function ( all, hr1, hr2, min, sec ) {
    return (hr1 || '0') + (hr2 || '0') + ':' + (min || '00') + '.' + sec;
  }
);
radi8
  • 528
  • 3
  • 12
  • 29
  • Why I downvoted this question: http://meta.stackexchange.com/a/149138/133242 – Matt Ball Apr 12 '13 at 16:53
  • how is 01:01:01 returned? – Lee Meador Apr 12 '13 at 16:54
  • Using only regex will not suffice. There's existing resources that can easily answer your question: https://www.google.ca/#hl=en&sclient=psy-ab&q=julian+to+date+javascript&oq=julian+to+date+javascript – Amy Apr 12 '13 at 16:57
  • 1
    The time element comes from the JDE ERP system. It is not a system julian format. In JDE's wisom (???) they decided to convert all dates to a human readable number and built internal classes to manage them. For example, April 12, 2013 is stored as 113102. 1-->13<-- is the year and 102 is the day of the year. All times are stored as numbers also, time is in the hhmmss format, so 1o'clock 1 minute and 1 sec AM would be 10101. Storing numbers in a DB is quicker and easier than parsing out date string (I guess). I didn't design it, JDE did. – radi8 Apr 12 '13 at 17:22
  • @AlexW Adding would not work because they are not the number of elapsed seconds since some base time. I've added some info to my answer about the incoming format. – Lee Meador Apr 12 '13 at 17:29

2 Answers2

2

The following works with your examples, though I haven't tested it beyond that

//var time = '01';
//var time = '2215';
//var time = '12215';
//var time = '74501';
var time = '192215';

time = time.replace( /^(?:(?:(\d)?(\d))?(\d\d))?(\d\d)$/,
  function ( all, hr1, hr2, min, sec ) {
    return (hr1 || '0') + (hr2 || '0') + ':' + (min || '00') + '.' + sec;
  }
);

Although it gives 07:45.01 not 7:45.01, so as to be in keeping with 01:22.15.

MikeM
  • 13,156
  • 2
  • 34
  • 47
1

I'll give you a clue:

  1. Convert returned value to a number.
  2. num % 100 is the seconds.
  3. (num / 100) % 100 is the minutes.
  4. (num / 10000) is the hours.
  5. If the hours is less than 12, use AM
  6. If the hours is 12 or more, use PM and further, if its 13 or more, subtract 12.

Another way to do it is to treat it as a string. But then you have to add enough leading zeros to get to length 6 and then break it into 2 character bits and convert each to an 'int' and that's way more work than just mod-ing by 100 and diving by 100 and 10,000.

There should never be a value in those two digit sections greater than 59.

Note

@radi8 noticed something I left out. I should have noted that the "/" (division) in the above algorithm has to be integer arithmetic for it to work right. Some programming languages offer integer arithmetic. JavaScript does not.

Since JavaScript uses floating point arithmetic, he subtracts off the number of seconds before dividing. Then a similar subtraction of the number of minutes fixes the next step.

You could also use Math.floor() after dividing to accomplish the same thing (since these are positive numbers).

Here is OP's code modified to do that:

$(function () {
    var val1 = 41215,hr=0,min=0,sec=0;
    sec = val1%100;
    val1 = Math.floor(val1 / 100);
    min = val1%100;
    hr = Math.floor(val1 / 100);
    // format the result. This example could show 1:1:1 instead of 01:01:01
    tst2 = hr.toString()+':'+min.toString()+'.'+sec.toString();
    alert(tst2.toString());
});
Lee Meador
  • 12,829
  • 2
  • 36
  • 42
  • minutes and seconds only go to 59. Lee Mador, thanks so much, this will get me going. I was going down that horrible road of doing substrings and it just got too ugly. Thanks all! – radi8 Apr 12 '13 at 17:10
  • Trust me! It will work if the incoming format is as I believe. – Lee Meador Apr 12 '13 at 17:27
  • I do not think numeric calculcation alone is the correct answer in any case. We are dealing with IEEE-754 "double-precision" floating-point values here. And later the OP has made the format clear; I do not see that you are handling the "year" and "day of year" components at all. – PointedEars Apr 12 '13 at 17:44
  • I am asking ONLY about the time element supplied by the ERP, I noted above the date format (Julian DAY, not Julian DATE). I apologize for the confusion. The solution to my little problem is detailed above. – radi8 Apr 12 '13 at 18:26