Forum Moderators: coopster

Message Too Old, No Replies

date() and negative timestamps

got custom functions?

         

httpwebwitch

4:29 am on Jun 13, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It's annoying that my server doesn't play well with negative timestamps (with mktime and date).

The world did exist before 1970, right? I can't vouch for that myself, but quite a few people older than me claim to have been around back then.

I want a version of date() and mktime() that don't "choke" on dates from the pre-disco era. (PDE)

Anyone?

WhosAWhata

4:48 am on Jun 13, 2004 (gmt 0)

10+ Year Member



check the user added comments at php.net i think they had one for date not sure about mktime

httpwebwitch

7:16 pm on Jun 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hiya,
I just want bump this one back up the forum, I'm still having problems with negative timestamps... Does anyone have a custom date() replacement function that doesn't choke on dates before 1970?

coopster

2:59 pm on Jun 21, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Where are you getting the negative timestamp? Or, more importantly, what data are you starting with, and what data are you trying to return?

httpwebwitch

5:18 pm on Jun 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'm getting the negative timestamp from a rather complicated astronomical ephemeris program, which computes the approximate position of planets at a given moment in time.

The computation is all done using Julian dates. Then to display the data I have some good accurate functions that translate the Julian date into a UNIX timestamp. With the date() function it's easier to create nice human-readable string like "January 13, 1986 at 13:06:03"

Everything is fine and very accurate so long as I don't request events before 1970. That's when the timestamp goes negative.

So I guess I could get by with a function like date() that accepts a Julian date rather than a UNIX timestamp, and offers all the nice formatting options.

I don't really understand why these functions have built-in limitations. I can't even use date() to show my Mom's birthday. Isn't that silly?

httpwebwitch

5:24 pm on Jun 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



January 1, 1970, 00:00:00 (Gregorian)
= 0 (UNIX timestamp)
= 1001150.5 (Julian Date)

Julian Date converter [aa.usno.navy.mil]

I might have to take this calculator (done with Javascript) and reporoduce it in PHP. That may work in my own special situation, but it doens't make the built-in date() function any less stupid.

coopster

9:31 pm on Jun 21, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Actually, it's not the PHP functions that are the issue, but more likely it is the fact that not all platforms (operating systems) support negative timestamps (negative timestamps are not supported under any known version of Windows). See the first Note on this page for more information:

[php.net...]




So I guess I could get by with a function like date() that accepts a Julian date rather than a UNIX timestamp, and offers all the nice formatting options.

No, that won't work. date() [php.net] accepts a timestamp value, not a julian date.



All that said, do you have MySQL installed? Or another database that has some more advanced DATE/TIME functions? Perhaps you could use your database server to get what you want by adding the negative date to the epoch, or wherever your negative value is starting from, and format that accordingly...

SELECT DATE_FORMAT(DATE_ADD('1970-01-01', INTERVAL your_value_here SECOND), '%W %M %Y');

MySQL Date and Time Functions [dev.mysql.com]

httpwebwitch

2:43 pm on Jun 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I understand. And, I am using Windows.

A timestamp is only a 32-bit signed integer, so the maximum range of dates possible is 1901-12-13 to 2038-19-01. On Windows, the range is 1970-01-01 to 2038-19-01.

To cover the span of time required for an astronomical ephemeris, timestamps aren't appropriate. Maybe if the timestamp was a 64-bit integer, it would be big enough to span from the big bang to armageddon. 32 doesn't cut the mustard.

There are two solutions I can think of:

1) PHP needs better date functions that aren't hampered by the limitations of the operating system. This means they would need to accept extra-large >32b timestamps using bcmath [ca2.php.net] arbitrary precision

2) a parallel set of functions that use Julian Days instead of timestamps.

note: JDToGregorian [ca2.php.net] is inaccurate and useless. Dates are off by up to 12 hours because it doesn't take into account that the Julian Days begin at noon, and it rounds off decimal fractions which correspond to the time of day.

coopster

4:20 pm on Jun 22, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



If the PHP Calendar Functions [php.net] aren't quite up to snuff you'll probably have to roll your own. There are some formulas found on the first linked site from there ( [hermetic.ch...] ).

The only other Calendar Functions I'm aware of in PHP are the mcal [php.net] functions. On a side note, I found this library that may be of some use to you...

[phplens.com...]

httpwebwitch

5:14 pm on Jun 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hey coopster, those functions [phplens.com] you found are working perfectly. Thanks! That's exactly what I needed.

It eliminates the 32-bit problem with timestamps using custom functions that use 64-bit floating numbers.

All I had to do is include the adodb_time library, and replace:
getdate() with adodb_getdate()
date() with adodb_date()
gmdate() with adodb_gmdate()
mktime() with adodb_mktime()
gmmktime() with adodb_gmmktime()

Since this thread might be useful to future generations of PHP coders, I should mention that I added my own function to the library to replace strtotime(). It isn't as versatile as the real strtotime, but since I always keep my dates in a standard format, it works well for parsing dates in the format "Y-m-d H:i:s" (YYYY-MM-DD HH:II:SS). That function is below.

It's also nice to see that the author did their research - the functions automatically correct themselves for the 10-day gap in the Gregorian Calendar in October of 1582. This may be confusing for algorithms that project the current calendar retroactively and uninterruptedly into the past, but it is good for corroborating actual historical events with a standard measure of time.

Actual time can be measured in Julian Days (NOT the same as the Julian Calendar!), which make the math easier when computing things like sunsets and moon phases. The JD time can then be translated nicely into the Gregorian calendar with all its human error and historical inconsistencies.

For historical reasons, the Gregorian calendar as used by humans doesn't always "sync up" with the results of a computed translation - some countries and colonies were quicker than others in adopting the Gregorian calendar, resulting in confusion between "Old Time" and "New Time", notwithstanding religious and political implications. There are many good books devoted to that subject.

function adodb_strtotime($instr){
// takes a time in format YYYY-MM-DD HH:II:SS
$y=substr($instr,0,4);
$m=substr($instr,5,2);
$d=substr($instr,8,2);
$h=substr($instr,11,2);
$i=substr($instr,14,2);
$s=substr($instr,17,2);
return adodb_mktime($h,$i,$s,$m,$d,$y);
}

coopster

5:54 pm on Jun 23, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Cool, glad it all panned out. Wish your mom a happy birthday for me :)