Template talk:JULIANDAY

Template:JULIANDAY(edit talk links history)

The formula used is in this template is :

  (((year * 12 + month + 57608.5 round 0) / 12 - 1.5 round 0) * 1461 / 4 - 0.5 round 0)
- (((year * 12 + month + 57608.5 round 0) / 12 - 1.5 round 0) / 100 - 0.5 round 0)
+ (((year * 12 + month + 57608.5 round 0) / 12 - 1.5 round 0) / 400 - 0.5 round 0)
+ ((            (month + 57608.5 round 0) mod 12 + 4) * 153 / 5 - 0.5 round 0)
+ day + hour / 24 + minute / 1440 + second / 86400
- 32167.5

The formulas allows using date elements that are out of range, for date computing (for example when adding or substracting any number of months, and it works even if these months span one or more leap years). You can also specify hours out of the normal range 0..23, minutes seconds out of 0..59. And days of month out of the normal month range (1..31), so you can also add or substract any number of days. It ignores leap seconds (the returned JD considers all days having 24 hours exactly).

Testing subst

edit

Optional substitution works if all optional parameters are specified, and the optional subst parameter is given as in:
{{subst:JULIANDAY|2006|12|31|23|59|59|subst=subst:}} = 2454101.49999
Without substitution:
{{JULIANDAY|2006|12|31|23|59|59}} = 2454101.4999884

Test suite

edit
Adapted from m:Template talk:YMD2MJD
Code Result MJD JD REXX
{{JULIANDAY|0000|03|01|0}} = 1721119.5 -678881 1721119.5 -306
{{JULIANDAY|0001|01|31|0}} = 1721455.5 -678545 1721455.5 30
{{JULIANDAY|0001|02|01|0}} = 1721456.5 -678544 1721456.5 31
{{JULIANDAY|0001|02|28|0}} = 1721483.5 -678517 1721483.5 58
{{JULIANDAY|0001|03|01|0}} = 1721484.5 -678516 1721484.5 59
{{JULIANDAY|0001|08|31|0}} = 1721667.5 -678333 1721667.5 242
{{JULIANDAY|0001|09|01|0}} = 1721668.5 -678332 1721668.5 243
{{JULIANDAY|0004|02|29|0}} = 1722579.5 -677421 1722579.5 1154
{{JULIANDAY|0004|03|01|0}} = 1722580.5 -677420 1722580.5 1155
{{JULIANDAY|1259|03|02|0}} = 2180960.5 -219040 2180960.5 459535
{{JULIANDAY|1516|12|30|0}} = 2275130.5 -124870 2275130.5 553705
{{JULIANDAY|1582|10|15|0}} = 2299160.5 -100840 2299160.5 577735
{{JULIANDAY|1752|09|14|0}} = 2361221.5 -38779 2361221.5 639796
{{JULIANDAY|1858|11|17|0}} = 2400000.5 0 2400000.5 678575
{{JULIANDAY|1895|02|28|0}} = 2413252.5 13252 2413252.5 691827
{{JULIANDAY|1895|03|01|0}} = 2413253.5 13253 2413253.5 691828
{{JULIANDAY|1896|02|29|0}} = 2413618.5 13618 2413618.5 692193
{{JULIANDAY|1896|03|01|0}} = 2413619.5 13619 2413619.5 692194
{{JULIANDAY|1900|02|28|0}} = 2415078.5 15078 2415078.5 693653
{{JULIANDAY|1900|03|01|0}} = 2415079.5 15079 2415079.5 693654
{{JULIANDAY|1970|01|01|0}} = 2440587.5 40587 2440587.5 719162
{{JULIANDAY|2000|02|29|0}} = 2451603.5 51603 2451603.5 730178
{{JULIANDAY|2000|03|01|0}} = 2451604.5 51604 2451604.5 730179
{{JULIANDAY|2738|11|28|0}} = 2721424.5 321424 2721424.5 999999
Examples adapted from Template:YMD2MJD (edit · talk · links · history) at Meta:
{{JULIANDAY|1900|02|28}} = 2415079, last day of February 1900
{{JULIANDAY|1900|02|29}} = 2415080, bogey but okay
{{JULIANDAY|1900|03|01}} = 2415080, no leap year
{{JULIANDAY|1900|02|30}} = 2415081, bogey but okay
{{JULIANDAY|1900|03|02}} = 2415081
{{JULIANDAY|2000|02|29}} = 2451604, last day of February 2000
{{JULIANDAY|2000|02|30}} = 2451605, bogey but okay
{{JULIANDAY|2000|03|01}} = 2451605, leap year
{{JULIANDAY|2000|02|31}} = 2451606, bogey but okay
{{JULIANDAY|2000|03|02}} = 2451606
{{JULIANDAY|2024|11|03}} = 2460618

Better examples

edit

Where do I go to get the current day of the year? Like is today the 108th day of 2008 or what? --Uncle Ed (talk) 17:27, 17 April 2008 (UTC)Reply

Response: {{#expr:{{JULIANDAY|2008|4|17}} - {{JULIANDAY|2007|12|31}}}} = 108
You can also use: {{#expr:{{JULIANDAY|2008|4|17}} - {{JULIANDAY|2008|1|0}}}} = 108
verdy_p (talk) 07:47, 3 July 2008 (UTC)Reply
For the current day of the year as of today (this page was last saved on 2024-11-3):
{{#expr:{{JULIANDAY|{{CURRENTYEAR}}|{{CURRENTMONTH}}|{{CURRENTDAY}}}} - {{JULIANDAY|{{CURRENTYEAR}}|1|0}}}} = 308.
verdy_p (talk) 07:54, 3 July 2008 (UTC)Reply

Separate parameters

edit

I'm wondering why the template separates each time component instead of accepting a single value. The #time: parser function is intelligent enough to understand multiple time formats and can be configured to output to any format. SharkD (talk) 04:51, 19 July 2008 (UTC)Reply

Nevermind. It's because of the 1 Jan 1970 cutoff. SharkD (talk) 05:35, 19 July 2008 (UTC)Reply
You can pass a single value for the time if you which, using fractional days or hours or minutes; several parameters are provided as convenience as they provide the correct factor for each of them.
The only complexity is the association between the simple group (year,month) on one side and the second simple group (day,hour,minute,second) on the other side, that are not combined with a simple factor to compute a real number of days since the arbitrary (but constant) date of epoch.
So if your time value is given as a number of second since midnight, pass it in the second field, and set the hour and minute fields to zero, and set the appropriate date fields (year,month,day).
If your date-time value is given as a number of second since another epoch, you actually don't need this template ; instead add the JULIANDAY value for that epoch (this is a constant, you can subst the template to compute that constant, or look into the documentation page for examples of such epochs), with the real number of days equivalent to your date-time value in seconds (you just need to divide it by 86400 to convert it from seconds to days).
Note that:
  • The Unix timestamps in seconds is actually not linear and does not return an exact duration in seconds, because this timestamp is adjusted to take onto account leap seconds in the UTC time, to allow "simple" calendrical calculations.
  • Astronomical timestamps on the opposite are NOT adjusted and remain fully linear (meaning that this clock drifts slightly from the UTC clock). It is not easy to convert astronomical timestamps or exact durations in SI seconds into timestamps, and in fact it's impossible to make a prediction on the long term (more than 6 months) between the two because the UTC adjustments are unpredictable (and subject to accidental modification of the Earth rotation to realign midday with a point of observation, such as major earthquakes or solar wind events, or to its revolution around the sun to realign the equinoxes).
  • As a consequence, the UTC clock is not providing an exact measure of time and durations in SI units, but attempts to produce a good approximation of dates and time of day (for a precision of +/- 2 seconds), using a conventional duration of exactly 24 UTC hours or 86400 UTC seconds for each day (UTC time units are NOT the same as SI time units, because they are not linear). There are some very complex conversion from UTC time to/from astronomical time, but this requires a growing lookup table whose content is adjusted every 6 months. verdy_p (talk) 20:34, 4 July 2011 (UTC)Reply

Contradiction

edit

This comment from http://en.wikipedia.org/wiki/Template:JULIANDAY

{{JULIANDAY|-4800|2|29|23|59|59}} returns -32044.500011574 (proleptic) (in year 4801 BC), last Gregorian date where the result is false (the returned JD is too large by 365 days)

contradicts this quote from http://en.wikipedia.org/wiki/Julian_day#Calculation

In the proleptic Gregorian calendar the Julian day zero is November 24, 4714 BC which is 32045 days apart from the start of the Gregorian quadricentennial cycle (i.e. 400-year cycle starting and ending in a year divisible by 400) containing the Julian day zero, which begins on March 1, 4801 BC in the proleptic Gregorian calendar.

--Erzbischof (talk) 15:49, 22 February 2009 (UTC)Reply

That's correct and we effectively get: {{JULIANDAY|-4713|11|24}}={{JULIANDAY|-4713|11|24|12|0|0}}=0 for this reference date, which is the day where the Julian calendar starts (on March 1, 4800 BC in that calendar). verdy_p (talk) 01:54, 4 July 2011 (UTC)Reply

Copied from Talk:Julian_day#Contradiction:

The template call {{quote|{{JULIANDAY|-4800|2|29|23|59|59}} actually returns -32044.500011574 which agrees with the converter available at http://www.fourmilab.ch/documents/calendar/ . That converter gives -32044.500011574073 and also indicates the date is April 7, -4801 in the Julian calendar. --Gerry Ashton (talk) 18:35, 22 February 2009 (UTC)Reply
So the template is corrupt, because {{JULIANDAY|-4800|3|1|0|0|0}} actually returns -32410.5, which is wrong if -32044.500011574 is right for the day before?? --Erzbischof (talk) 08:37, 23 February 2009 (UTC)Reply
Yes, the Julian date for March 1, -4800 Gregorian is indeed wrong. --Gerry Ashton (talk) 15:27, 23 February 2009 (UTC)Reply
Actually no ! You have forgotten that fourmilab.ch counts BC years starting at 1 in a different era, instead of a linear year counting with negative value... Reread the documentation, the BC years must be specified using the astronomical counting, i.e. year 1 BC is entered as "0". This avoids all tests and duplication of code and allows some linear arithmetics on years passed in parameters without having to test the value. If you want to pass BC years with negative values, you have to increment it towards zero to convert it to the single era...
This template does the correct thing starting in 1st March, 4801 BC (passed as -4800), but will also fail only before that date by rounding up to the next quadrisecular period instead of rounding down to the last quadrisecular period. I have not been searching which date of origin fourmilab.ch uses, but it does not go so far in the history. This is a common problem when using modular arithmetic : the rounding function needed to perform modular arithmetic should be a true mathematical floor() function, instead of a function symetric around zero ; this template avoids the problem by fixing its epoch far away in the history in 4801 BC.
Note that we now have the true floor() function in Wikimedia : we could use it instead of "round 0" to go even further in the past when converting years&months to a number of seconds (nothing is wrong with days, hours, minutes, seconds here, except that we don't handle unpredictable leap seconds that occur in very irregular patterns and were not usable before 20th century, and that we don't account for the slow drift in duration of terrestrial day that may be needed for very precise astronomical use or nuclear measurements because this template is for calendrical calculation only). verdy_p (talk) 01:18, 4 July 2011 (UTC)Reply

Suggestion for better code

edit

Please take a look at this code from JULIANDAY template of Korean Wikipedia:

<includeonly>{{{{{|safesubst:}}}#if:{{{1|}}}
|{{{{{|safesubst:}}}#expr:trunc(
floor((({{{1}}})*12+({{{2|1}}})-3)*365/12+0.96)
+floor(((((({{{2|1}}})-3) mod 12)+12) mod 12)/5.4)
+floor((({{{1}}})*12+({{{2|1}}})-3)/48)
+({{{{{|safesubst:}}}#ifexpr:(0{{{7|}}})<0
 |((({{{1}}})<({{{8|1582}}}))
 or ((({{{1}}})=({{{8|1582}}})) and (({{{2|1}}})<({{{9|10}}})))
 or ((({{{1}}})=({{{8|1582}}})) and (({{{2|1}}})=({{{9|10}}})) and (({{{3|1}}})<({{{10|15}}})))
 or ((({{{1}}})=({{{8|1582}}})) and (({{{2|1}}})=({{{9|10}}})) and (({{{3|1}}})=({{{10|15}}})) and (({{{4|12}}})<12)))
 |(0{{{7|}}})
 }}=0)*(2 - floor((({{{1}}})*12+({{{2|1}}})-3)/1200) + floor((({{{1}}})*12+({{{2|1}}})-3)/4800))
+1721117
+({{{3|1}}})
){{{{{|safesubst:}}}#ifexpr:(({{{4|12}}})=12) and (({{{5|0}}})=0) and (({{{6|0}}})=0)||
 +({{{4|12}}}-12)/24
 +({{{5|0}}})/1440
 +({{{6|0}}})/86400
 }}
}}
|<strong class="error">Error: Parameter 1=''year'' required!</strong>
}}</includeonly><noinclude>{{Documentation}}</noinclude>

This code unifies all functions of current {{JD}}, {{JULIANDAY}}, {{JULIANDAY.JULIAN}}. When its 7th Parameter is 0, it works like {{JULIANDAY}}. And works like {{JULIANDAY.JULIAN}} at 1, {{JD}} at -1. Furthermore, it is possible to specify certain date for change of calendar on parameter 8, 9, 10. Current {{JD}} has fixed beginning date of Gregorian calendar to 1582-10-15, but this code can specify various date, for example, 1752-09-14(for Great Britain).

Several bugs are also solved in this code. First of all, it can calculate any date from 19 March -2742563 to 15 October 2733138, at precision of 1 second. If there are no hours/mins/secs, even further range can be calculated exactly: from 1 June -2283105023 to 31 December 2283105022 at 1 day precision. On current JULIANDAY template, There are wrong calculations from 1 March -4800 to 28 February -4799.

Yes but these bugs are easily solved by replacing "(x round 0)" by "floor(x)" (but also "x mod y" by "x-floor(x/y)*y", unless there's a true "mod(x,y)" function doing the same thing) in the existing code.
The way the template was written in the past was limited to using the "round 0" operations (also also avoiding 32-bit integer overflows) because mathematic "floor()" was not implemented in MediaWiki (and at that time, support for "floor()" was still refused after many requests and it was only introduced along with other maths functions like "ceil()", "cos()", "sin()", "tan()", "log()", "exp()" and "abs()").
But if "floor()" is used now, many additive constants used in the formula to avoid negative values (notably for years, but also for comptuing months in year) could be easily reduced to lower values (with a reduced byte count in the code).
Anyway, the template still works with older versions of MediaWiki without the additional maths functions supported by "#expr" in the ParserFunctions module, for absolutely all dates since March 4800 BC (proleptic Gregorian), i.e. still 85 years before the traditional epoch since the start of the Julian calendar (where JULIANDAY returns 0), and at least for all humane historic dates, as well as in many centuries in the future (the limit is the precision of doubles in the return value). verdy_p (talk) 04:19, 4 July 2011 (UTC)Reply
We don't need to avoid including "floor()", because now wikipedia supports its use. English WP does, either does Korean WP. Even if there are several wikipedias that are using old version of MW and they have problem with "floor()", it is their problem. Not of English WP. Is there any reason that we should not use error-free code for further range of date?
(off topic) By the way, some examples on documentation are wrong. Current template code outputs valid result from 1 March -4799 (4800 BC), not -4800 (4801 BC). --Alphanis (talk) 13:01, 7 July 2011 (UTC)Reply

Second of all, it uses "trunc" calculation to solve bugzilla:26738. So its output is "2400000" on 1858-11-16, not "2.4E+6".

Warning: truncation of the result will not work as the template has to take time into account (including for time offsets of more than 24 hours and negative time offsets), so it has to return fractional values for many other calendric computations.
Note that "2.4E6" is not incorrect and evaluates correctly when reevaluated in an outer #expr. It is not caused by rounding errors, but by the intent, in the number to string formater of PHP, to reduce the string length to its minimum when it is a double ; the PHP "trunc()" function still returns a double that will be converted to a string by MediaWiki, and not an integer type as returned by "round 0" (and that would overflow easily).
I don't think that your "trunc()" will be a solution, when it will remove functionality for time-related calculation. Proof: {{#expr:trunc(2400000)+0/86400}} = 2400000, but {{#expr:trunc(2400000)}} = 2400000 -- verdy_p (talk) 04:19, 4 July 2011 (UTC)Reply
See:
  • {{#expr:2400000.0}} = 2400000 : this is the display when the #expr value is a floating point value.
  • {{#expr:2400000}} = 2400000 : this is the display when the #expr value is restricted to a 32-bit integer value (no difference, #expr still computes doubles and formats them this way).
  • {{#expr:2400000.00000001}} = 2400000 : this is the display when the computed double is in fact NOT an exact integer (#expr is eliminating some extra precision digits when formating the result, and then drops the remaining zeroes, so it does not display all digits needed to reach the full precision of doubles).
Proof:
  • {{#expr:2400000.0 - 2.4E6}} = 0
  • {{#expr:2400000 - 2.4E6}} = 0
  • {{#expr:2400000.00000001 - 2.4E6}} = 9.7788870334625E-9
verdy_p (talk) 20:51, 4 July 2011 (UTC)Reply
Sure I know that "trunc()" removes fractions and exponent will be calculated correctly as "number".
This is old, I know, but trunc() is incorrect with modular arithmetic (we have negative values to take into account in some range, that's whay the formula used some carefully chosen additive constants). What you mean is not trunct() but floor(). See the previous section. The formular was written in a time where neither floor() nor trunc() was availabel in expressions. Otherwise it would have been a bit simpler with trunc(), not floor(). verdy_p (talk) 12:41, 25 April 2016 (UTC)Reply
Please look above code carefully. It uses "trunc()" for interger part(year, month, day) only, and evaluates correct value for time offsets more than 24 or 60 and negative offsets, because they will be calculated as float(or double). That code is working fine on Korean wikipedia currently. --Alphanis (talk) 13:01, 7 July 2011 (UTC)Reply

I also think integration of three templates into one will makes better its performance on server because of fetch and reduction of template-expand. --Alphanis (talk) 21:06, 28 May 2011 (UTC)Reply

Decrease to semi-protection

edit

Why is this template in full-protection? Can you provide the usage details of this template? Or else can you please decrease the protection level to semi-protection so that others can edit? Wetitpig0 (talk) 01:06, 4 September 2016 (UTC)Reply

Merging

edit

Wetitpig0 (talk) 01:09, 4 September 2016 (UTC)Reply

  Donexaosflux Talk 04:20, 4 September 2016 (UTC)Reply

Protected edit request on 17 September 2016

edit

I just closed the tfm discussion linked as keep, and thus am now requesting that the tfm tag be removed. Pppery 01:28, 17 September 2016 (UTC)Reply

  Donexaosflux Talk 03:07, 17 September 2016 (UTC)Reply