Overriding < in Pharo - overriding

I am trying to override the '<' operator in pharo, because i want to have a SortedCollection of a class i have implemented (TimeCal).
TimeCal has the following variables: year month day hour minute.
My idea was to convert all the variables to minutes, and then compare those with the comparand that the < operator receives. I do, however, get an error
"BlockClosure(Object)>>doesNotUnderstand: #>"
And here is my code:
< comparand
| thisInMins comparandInMins |
thisInMins := [(year * 525600) + (month * 43829) + (day * 1440) + (hour * 60) + minute].
comparandInMins := [(comparand year * 525600) + (comparand month * 43829) + (comparand day * 1440) + (comparand hour * 60) + comparand minute].
(thisInMins > comparandInMins)
ifTrue: [true] ifFalse: [false]
And the code i use to test it:
time1 := TimeCal new.
time1 hour: 12.
time1 day: 12.
time1 month: 11.
time2 := TimeCal new.
time2 hour: 12.
time2 day: 12.
time2 month: 8.
testing := time1 < time2.
I am not sure if what I am doing is correct. I could not find any proper guide on how to do it.

What about this
< other
year = other year ifFalse: [^year < other year].
month = other month ifFalse: [^month < other month].
day = other day ifFalse: [^day < other day].
hour = other hour ifFalse: [^hour < other hour].
^minute < other minute

If you have properly initialized your variables, this should work:
< comparand
| thisInMins comparandInMins |
thisInMins := (year * 525600) + (month * 43829) + (day * 1440) + (hour * 60) + minute.
comparandInMins := (comparand year * 525600) + (comparand month * 43829) + (comparand day * 1440) + (comparand hour * 60) + comparand minute.
^ thisInMins < comparandInMins
Why did you put square brackets around your minutes calculations?
Also have a look at this: ifTrue: [true] ifFalse: [false]. Returning true if something is true and false if something is false seems an unnecessary step. You can return the result of your comparison of minutes directly.

Related

I have some diffculty count a(n) = the number of Niven (Harshad) numbers exceeding N

Harshad/Niven numbers are positive numbers that are divisible by the sum of their digits. All single-digit numbers are Harshad numbers.
For example, 27 is a Harshad number as 2 + 7 = 9, and 9 is a divisor of 27.Count a(n) = the number of Niven (Harshad) numbers exceeding n (n<=1e12)
We can define the function checkHarshad(n) (Calculate sum of digits of n and check whether n%S(n)), then count the number of Harshad numbers in range [1..n]. But the program just run fast if n <= 1e7
Hiroaki Yamanouchi had a python code that calculate a(10^n), but I don't understand it, and I don't think it's helpful to my problem if n <= 1e12.
def number_of_niven_numbers(digits):
"""
- Count the number of Niven numbers
less than or equal to 10^digits.
"""
N = digits
ret = 0
cnts = [0] * (digits + 1)
for digit_sum in range(1, N * 9 + 1):
curr = [[0] * digit_sum]
curr[0][0] = 1
next_mods = [0] * digit_sum
for i in range(digit_sum):
next_mods[i] = 10 * i % digit_sum
for left_digits in range(N):
left_sum_max = min(9 * left_digits, digit_sum)
next = [[0] * digit_sum for _ in range(min(left_sum_max + 9, digit_sum) + 1)]
for left_sum in range(left_sum_max + 1):
for left_mod in range(digit_sum):
cnt = curr[left_sum][left_mod]
if cnt == 0:
continue
next_mod_base = next_mods[left_mod]
for next_digit in range(min(min(digit_sum, 9), digit_sum - left_sum) + 1):
next_sum = left_sum + next_digit
next_mod = next_mod_base + next_digit
if next_mod >= digit_sum:
next_mod -= digit_sum
next[next_sum][next_mod] += cnt
curr = next
if digit_sum < len(curr):
cnts[left_digits + 1] += curr[digit_sum][0]
return cnts[N] + 1
So, how can we calculate a(n) up to 1e12?

Time Function in Progress 4GL

I would like to insert 2 shift timings to the code.
(First Shift)
Shift starts from 8:00:00:000 to 19:59:59:999
(Second Shift)
Shift Starts from 20:00:00:000 to next day 7:59:59:999
I need to get the above exact data to be added to the below code.
Please help.
Below is the code:
IF TIME < (20 * 60 * 60) THEN DO:
ASSIGN StartDDT = dt_tm2dec(DATE(TODAY), 0)
EndDDT = dt_tm2dec(DATE(TODAY),19 * 60 * 60 + 59 * 60 + 59).
END.
ELSE DO:
ASSIGN StartDDT = dt_tm2dec(DATE(TODAY),20 * 60 * 60).
EndDDT = dt_tm2dec(DATE(TODAY + 1),07 * 60 * 60 + 59 * 60 + 59).
END.
The conditions you specified can be written as:
if ( time >= ( 8 * 60 * 60 )) and ( time < ( 20 * 60 * 60 )) then
do:
message "first shift".
end.
else
do:
message "second shift".
end.
You can use the DATETIME datatype to get millisecond accuracy on your times. Build the shift times with the DATETIME function, then compare your time to them. The NOW function gives you the current time down to the millisecond:
DEFINE VARIABLE dtShift1 AS DATETIME NO-UNDO.
DEFINE VARIABLE dtShift2 AS DATETIME NO-UNDO.
ASSIGN
dtShift1 = DATETIME(TODAY, (8 * 60 * 60 * 1000))
dtShift2 = DATETIME(TODAY, (20 * 60 * 60 * 1000)).
IF NOW >= dtShift1 AND NOW < dtShift2 THEN
MESSAGE "First shift" VIEW-AS ALERT-BOX INFORMATION.
ELSE
MESSAGE "Second shift" VIEW-AS ALERT-BOX INFORMATION.
You can also check the shift time for the following day by adding a day to TODAY:
dtShift1 = DATETIME(TODAY + 1, (8 * 60 * 60 * 1000))
And if you need to handle different time zones, use the DATETIME-TZ datatype.

Week Days deduction in code in Ax 2009

We have a from date and To date in Table fields.
We are getting an int value(Tot days) by using minus of To date from From Date.
Totdays = Todate - FromDate;
Up to here it is fine but problem arises if we have weekdays in the range between from date to Todate.
How to write X++ code to deduct weekdays in the range and get TotDays based on workingdays.
Days between two dates not counting Saturday and Sunday:
static void WorkDayDiff(Args _args)
{
int i;
Days workDayDiff(date d1, date d2)
{
Days y1 = dayofwk(d1); // Day of week 1
Days y2 = dayofwk(d2); // Day of week 2
date t1 = d1 - y1; // Sunday before d1
date t2 = d2 - y2; // Sunday before d2
Days y3 = (t2 - t1) div 7 * 5; // Work days between Sundays
Days y4 = min(y1-1,5); // Work days before d1
Days y5 = min(y2,5); // Work days after t2
return y3 - y4 + y5 - 1; // Work days between d1 and d2
}
;
setprefix(strFmt("Today %1 %2", today(), dayname(dayofwk(today()))));
for (i = -10; i <= 10; i++)
info(strFmt("Diff %1 %2 = %3", today()+i, dayname(dayofwk(today()+i)), int2str(workDayDiff(today(), today() + i))));
}
The count is negative if d2 is less than d1, but it may not be what you expect.

Function to return date of Easter for the given year

So, here's a funny little programming challenge. I was writing a quick method to determine all the market holidays for a particular year, and then I started reading about Easter and discovered just how crazy* the logic is for determining its date--the first Sunday after the Paschal Full Moon following the spring equinox! Does anybody know of an existing function to calculate the date of Easter for a given year?
Granted, it's probably not all that hard to do; I just figured I'd ask in case somebody's already done this. (And that seems very likely.)
UPDATE: Actually, I'm really looking for the date of Good Friday (the Friday before Easter)... I just figured Easter would get me there. And since I'm in the U.S., I assume I'm looking for the Catholic Easter? But perhaps someone can correct me on that if I'm wrong.
*By "crazy" I meant, like, involved. Not anything offensive...
Python: using dateutil's easter() function.
>>> from dateutil.easter import *
>>> print easter(2010)
2010-04-04
>>> print easter(2011)
2011-04-24
The functions gets, as an argument, the type of calculation you like:
EASTER_JULIAN = 1
EASTER_ORTHODOX = 2
EASTER_WESTERN = 3
You can pick the one relevant to the US.
Reducing two days from the result would give you Good Friday:
>>> from datetime import timedelta
>>> d = timedelta(days=-2)
>>> easter(2011)
datetime.date(2011, 4, 24)
>>> easter(2011)+d
datetime.date(2011, 4, 22)
Oddly enough, someone was iterating this, and published the results in Wikipedia's article about the algorithm:
in SQL Server Easter Sunday would look like this, scroll down for Good Friday
CREATE FUNCTION dbo.GetEasterSunday
( #Y INT )
RETURNS SMALLDATETIME
AS
BEGIN
DECLARE #EpactCalc INT,
#PaschalDaysCalc INT,
#NumOfDaysToSunday INT,
#EasterMonth INT,
#EasterDay INT
SET #EpactCalc = (24 + 19 * (#Y % 19)) % 30
SET #PaschalDaysCalc = #EpactCalc - (#EpactCalc / 28)
SET #NumOfDaysToSunday = #PaschalDaysCalc - (
(#Y + #Y / 4 + #PaschalDaysCalc - 13) % 7
)
SET #EasterMonth = 3 + (#NumOfDaysToSunday + 40) / 44
SET #EasterDay = #NumOfDaysToSunday + 28 - (
31 * (#EasterMonth / 4)
)
RETURN
(
SELECT CONVERT
( SMALLDATETIME,
RTRIM(#Y)
+ RIGHT('0'+RTRIM(#EasterMonth), 2)
+ RIGHT('0'+RTRIM(#EasterDay), 2)
)
)
END
GO
Good Friday is like this and it uses the Easter function above
CREATE FUNCTION dbo.GetGoodFriday
(
#Y INT
)
RETURNS SMALLDATETIME
AS
BEGIN
RETURN (SELECT dbo.GetEasterSunday(#Y) - 2)
END
GO
From here: http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
When it came for me to write this (traffic prediction based on day of week and holiday),
I gave up on trying to write it by myself. I found it somewhere on the net. The code was public domain, but...
sigh
see for yourself.
void dateOfEaster(struct tm* p)
{
int Y = p->tm_year;
int a = Y % 19;
int b = Y / 100;
int c = Y % 100;
int d = b / 4;
int e = b % 4;
int f = (b + 8) / 25;
int g = (b - f + 1) / 3;
int h = (19 * a + b - d - g + 15) % 30;
int i = c / 4;
int k = c % 4;
int L = (32 + 2 * e + 2 * i - h - k) % 7;
int m = (a + 11 * h + 22 * L) / 451;
p->tm_mon = ((h + L - 7 * m + 114) / 31 ) - 1;
p->tm_mday = ((h + L - 7 * m + 114) % 31) + 1;
p->tm_hour = 12;
const time_t tmp = mktime(p);
*p = *localtime(&tmp); //recover yday from mon+mday
}
Some questions are better left unasked.
I feel lucky that all moving holidays in my country are a fixed offset from the date of Easter.
The SQL Server function below is more general than the accepted answer
The accepted answer is only correct for the range (inclusive) : 1900-04-15 to 2099-04-12
It uses the algorithm provided by The United States Naval Observatory (USNO)
http://aa.usno.navy.mil/faq/docs/easter.php
CREATE FUNCTION dbo.GetEasterSunday (#Y INT)
RETURNS DATETIME
AS
BEGIN
-- Source of algorithm : http://aa.usno.navy.mil/faq/docs/easter.php
DECLARE #c INT = #Y / 100
DECLARE #n INT = #Y - 19 * (#Y / 19)
DECLARE #k INT = (#c - 17) / 25
DECLARE #i INT = #c - #c / 4 - (#c - #k) / 3 + 19 * #n + 15
SET #i = #i - 30 * (#i / 30)
SET #i = #i - (#i / 28) * (1 - (#i / 28) * (29 / (#i + 1)) * ((21 - #n) / 11))
DECLARE #j INT = #Y + #Y / 4 + #i + 2 - #c + #c / 4
SET #j = #j - 7 * (#j / 7)
DECLARE #l INT = #i - #j
DECLARE #m INT = 3 + (#l + 40) / 44
DECLARE #d INT = #l + 28 - 31 * (#m / 4)
RETURN
(
SELECT CONVERT
( DATETIME,
RTRIM(#Y)
+ RIGHT('0'+RTRIM(#m), 2)
+ RIGHT('0'+RTRIM(#d), 2)
)
)
END
GO
VB .NET Functions for Greek Orthodox and Catholic Easter:
Public Shared Function OrthodoxEaster(ByVal Year As Integer) As Date
Dim a = Year Mod 19
Dim b = Year Mod 7
Dim c = Year Mod 4
Dim d = (19 * a + 16) Mod 30
Dim e = (2 * c + 4 * b + 6 * d) Mod 7
Dim f = (19 * a + 16) Mod 30
Dim key = f + e + 3
Dim month = If((key > 30), 5, 4)
Dim day = If((key > 30), key - 30, key)
Return New DateTime(Year, month, day)
End Function
Public Shared Function CatholicEaster(ByVal Year As Integer) As DateTime
Dim month = 3
Dim a = Year Mod 19 + 1
Dim b = Year / 100 + 1
Dim c = (3 * b) / 4 - 12
Dim d = (8 * b + 5) / 25 - 5
Dim e = (5 * Year) / 4 - c - 10
Dim f = (11 * a + 20 + d - c) Mod 30
If f = 24 Then f += 1
If (f = 25) AndAlso (a > 11) Then f += 1
Dim g = 44 - f
If g < 21 Then g = g + 30
Dim day = (g + 7) - ((e + g) Mod 7)
If day > 31 Then
day = day - 31
month = 4
End If
Return New DateTime(Year, month, day)
End Function
The below code determines Easter through powershell:
function Get-DateOfEaster {
param(
[Parameter(ValueFromPipeline)]
$theYear=(Get-Date).Year
)
if($theYear -lt 1583) {
return $null
} else {
# Step 1: Divide the theYear by 19 and store the
# remainder in variable A. Example: If the theYear
# is 2000, then A is initialized to 5.
$a = $theYear % 19
# Step 2: Divide the theYear by 100. Store the integer
# result in B and the remainder in C.
$c = $theYear % 100
$b = ($theYear -$c) / 100
# Step 3: Divide B (calculated above). Store the
# integer result in D and the remainder in E.
$e = $b % 4
$d = ($b - $e) / 4
# Step 4: Divide (b+8)/25 and store the integer
# portion of the result in F.
$f = [math]::floor(($b + 8) / 25)
# Step 5: Divide (b-f+1)/3 and store the integer
# portion of the result in G.
$g = [math]::floor(($b - $f + 1) / 3)
# Step 6: Divide (19a+b-d-g+15)/30 and store the
# remainder of the result in H.
$h = (19 * $a + $b - $d - $g + 15) % 30
# Step 7: Divide C by 4. Store the integer result
# in I and the remainder in K.
$k = $c % 4
$i = ($c - $k) / 4
# Step 8: Divide (32+2e+2i-h-k) by 7. Store the
# remainder of the result in L.
$l = (32 + 2 * $e + 2 * $i - $h - $k) % 7
# Step 9: Divide (a + 11h + 22l) by 451 and
# store the integer portion of the result in M.
$m = [math]::floor(($a + 11 * $h + 22 * $l) / 451)
# Step 10: Divide (h + l - 7m + 114) by 31. Store
# the integer portion of the result in N and the
# remainder in P.
$p = ($h + $l - 7 * $m + 114) % 31
$n = (($h + $l - 7 * $m + 114) - $p) / 31
# At this point p+1 is the day on which Easter falls.
# n is 3 for March and 4 for April.
$DateTime = New-Object DateTime $theyear, $n, ($p+1), 0, 0, 0, ([DateTimeKind]::Utc)
return $DateTime
}
}
$eastersunday=Get-DateOfEaster 2015
Write-Host $eastersunday
Found this Excel formula somewhere
Assuming cell A1 contains year e.g. 2020
ROUND(DATE(A1;4;1)/7+MOD(19*MOD(A1;19)-7;30)*0,14;0)*7-6
Converted to T-SQL lead me to this:
DECLARE #yr INT=2020
SELECT DATEADD(dd, ROUND(DATEDIFF(dd, '1899-12-30', DATEFROMPARTS(#yr, 4, 1)) / 7.0 + ((19.0 * (#yr % 19) - 7) % 30) * 0.14, 0) * 7.0 - 6, -2)
In JS, taken from here.
var epoch=2444238.5,elonge=278.83354,elongp=282.596403,eccent=.016718,sunsmax=149598500,sunangsiz=.533128,mmlong=64.975464,mmlongp=349.383063,mlnode=151.950429,minc=5.145396,mecc=.0549,mangsiz=.5181,msmax=384401,mparallax=.9507,synmonth=29.53058868,lunatbase=2423436,earthrad=6378.16,PI=3.141592653589793,epsilon=1e-6;function sgn(x){return x<0?-1:x>0?1:0}function abs(x){return x<0?-x:x}function fixAngle(a){return a-360*Math.floor(a/360)}function toRad(d){return d*(PI/180)}function toDeg(d){return d*(180/PI)}function dsin(x){return Math.sin(toRad(x))}function dcos(x){return Math.cos(toRad(x))}function toJulianTime(date){var year,month,day;year=date.getFullYear();var m=(month=date.getMonth()+1)>2?month:month+12,y=month>2?year:year-1,d=(day=date.getDate())+date.getHours()/24+date.getMinutes()/1440+(date.getSeconds()+date.getMilliseconds()/1e3)/86400,b=isJulianDate(year,month,day)?0:2-y/100+y/100/4;return Math.floor(365.25*(y+4716)+Math.floor(30.6001*(m+1))+d+b-1524.5)}function isJulianDate(year,month,day){if(year<1582)return!0;if(year>1582)return!1;if(month<10)return!0;if(month>10)return!1;if(day<5)return!0;if(day>14)return!1;throw"Any date in the range 10/5/1582 to 10/14/1582 is invalid!"}function jyear(td,yy,mm,dd){var z,f,alpha,b,c,d,e;return f=(td+=.5)-(z=Math.floor(td)),b=(z<2299161?z:z+1+(alpha=Math.floor((z-1867216.25)/36524.25))-Math.floor(alpha/4))+1524,c=Math.floor((b-122.1)/365.25),d=Math.floor(365.25*c),e=Math.floor((b-d)/30.6001),{day:Math.floor(b-d-Math.floor(30.6001*e)+f),month:Math.floor(e<14?e-1:e-13),year:Math.floor(mm>2?c-4716:c-4715)}}function jhms(j){var ij;return j+=.5,ij=Math.floor(86400*(j-Math.floor(j))+.5),{hour:Math.floor(ij/3600),minute:Math.floor(ij/60%60),second:Math.floor(ij%60)}}function jwday(j){return Math.floor(j+1.5)%7}function meanphase(sdate,k){var t,t2;return 2415020.75933+synmonth*k+1178e-7*(t2=(t=(sdate-2415020)/36525)*t)-155e-9*(t2*t)+33e-5*dsin(166.56+132.87*t-.009173*t2)}function truephase(k,phase){var t,t2,t3,pt,m,mprime,f,apcor=!1;if(pt=2415020.75933+synmonth*(k+=phase)+1178e-7*(t2=(t=k/1236.85)*t)-155e-9*(t3=t2*t)+33e-5*dsin(166.56+132.87*t-.009173*t2),m=359.2242+29.10535608*k-333e-7*t2-347e-8*t3,mprime=306.0253+385.81691806*k+.0107306*t2+1236e-8*t3,f=21.2964+390.67050646*k-.0016528*t2-239e-8*t3,phase<.01||abs(phase-.5)<.01?(pt+=(.1734-393e-6*t)*dsin(m)+.0021*dsin(2*m)-.4068*dsin(mprime)+.0161*dsin(2*mprime)-4e-4*dsin(3*mprime)+.0104*dsin(2*f)-.0051*dsin(m+mprime)-.0074*dsin(m-mprime)+4e-4*dsin(2*f+m)-4e-4*dsin(2*f-m)-6e-4*dsin(2*f+mprime)+.001*dsin(2*f-mprime)+5e-4*dsin(m+2*mprime),apcor=!0):(abs(phase-.25)<.01||abs(phase-.75)<.01)&&(pt+=(.1721-4e-4*t)*dsin(m)+.0021*dsin(2*m)-.628*dsin(mprime)+.0089*dsin(2*mprime)-4e-4*dsin(3*mprime)+.0079*dsin(2*f)-.0119*dsin(m+mprime)-.0047*dsin(m-mprime)+3e-4*dsin(2*f+m)-4e-4*dsin(2*f-m)-6e-4*dsin(2*f+mprime)+.0021*dsin(2*f-mprime)+3e-4*dsin(m+2*mprime)+4e-4*dsin(m-2*mprime)-3e-4*dsin(2*m+mprime),pt+=phase<.5?.0028-4e-4*dcos(m)+3e-4*dcos(mprime):4e-4*dcos(m)-.0028-3e-4*dcos(mprime),apcor=!0),!apcor)throw"Error calculating moon phase!";return pt}function phasehunt(sdate,phases){var adate,k1,k2,nt1,nt2,yy,mm,dd,jyearResult=jyear(adate=sdate-45,yy,mm,dd);for(yy=jyearResult.year,mm=jyearResult.month,dd=jyearResult.day,adate=nt1=meanphase(adate,k1=Math.floor(12.3685*(yy+1/12*(mm-1)-1900)));nt2=meanphase(adate+=synmonth,k2=k1+1),!(nt1<=sdate&&nt2>sdate);)nt1=nt2,k1=k2;return phases[0]=truephase(k1,0),phases[1]=truephase(k1,.25),phases[2]=truephase(k1,.5),phases[3]=truephase(k1,.75),phases[4]=truephase(k2,0),phases}function kepler(m,ecc){var e,delta;e=m=toRad(m);do{e-=(delta=e-ecc*Math.sin(e)-m)/(1-ecc*Math.cos(e))}while(abs(delta)>epsilon);return e}function getMoonPhase(julianDate){var Day,N,M,Ec,Lambdasun,ml,MM,MN,Ev,Ae,MmP,mEc,lP,lPP,NP,y,x,MoonAge,MoonPhase,MoonDist,MoonDFrac,MoonAng,F,SunDist,SunAng;return N=fixAngle(360/365.2422*(Day=julianDate-epoch)),Ec=kepler(M=fixAngle(N+elonge-elongp),eccent),Ec=Math.sqrt((1+eccent)/(1-eccent))*Math.tan(Ec/2),Lambdasun=fixAngle((Ec=2*toDeg(Math.atan(Ec)))+elongp),F=(1+eccent*Math.cos(toRad(Ec)))/(1-eccent*eccent),SunDist=sunsmax/F,SunAng=F*sunangsiz,ml=fixAngle(13.1763966*Day+mmlong),MM=fixAngle(ml-.1114041*Day-mmlongp),MN=fixAngle(mlnode-.0529539*Day),MmP=MM+(Ev=1.2739*Math.sin(toRad(2*(ml-Lambdasun)-MM)))-(Ae=.1858*Math.sin(toRad(M)))-.37*Math.sin(toRad(M)),lPP=(lP=ml+Ev+(mEc=6.2886*Math.sin(toRad(MmP)))-Ae+.214*Math.sin(toRad(2*MmP)))+.6583*Math.sin(toRad(2*(lP-Lambdasun))),NP=MN-.16*Math.sin(toRad(M)),y=Math.sin(toRad(lPP-NP))*Math.cos(toRad(minc)),x=Math.cos(toRad(lPP-NP)),toDeg(Math.atan2(y,x)),NP,toDeg(Math.asin(Math.sin(toRad(lPP-NP))*Math.sin(toRad(minc)))),MoonAge=lPP-Lambdasun,MoonPhase=(1-Math.cos(toRad(MoonAge)))/2,MoonDist=msmax*(1-mecc*mecc)/(1+mecc*Math.cos(toRad(MmP+mEc))),MoonAng=mangsiz/(MoonDFrac=MoonDist/msmax),mparallax/MoonDFrac,{moonIllumination:MoonPhase,moonAgeInDays:synmonth*(fixAngle(MoonAge)/360),distanceInKm:MoonDist,angularDiameterInDeg:MoonAng,distanceToSun:SunDist,sunAngularDiameter:SunAng,moonPhase:fixAngle(MoonAge)/360}}function getMoonInfo(date){return null==date?{moonPhase:0,moonIllumination:0,moonAgeInDays:0,distanceInKm:0,angularDiameterInDeg:0,distanceToSun:0,sunAngularDiameter:0}:getMoonPhase(toJulianTime(date))}function getEaster(year){var previousMoonInfo,moonInfo,fullMoon=new Date(year,2,21),gettingDarker=void 0;do{previousMoonInfo=getMoonInfo(fullMoon),fullMoon.setDate(fullMoon.getDate()+1),moonInfo=getMoonInfo(fullMoon),void 0===gettingDarker?gettingDarker=moonInfo.moonIllumination<previousMoonInfo.moonIllumination:gettingDarker&&moonInfo.moonIllumination>previousMoonInfo.moonIllumination&&(gettingDarker=!1)}while(gettingDarker&&moonInfo.moonIllumination<previousMoonInfo.moonIllumination||!gettingDarker&&moonInfo.moonIllumination>previousMoonInfo.moonIllumination);for(fullMoon.setDate(fullMoon.getDate()-1);0!==fullMoon.getDay();)fullMoon.setDate(fullMoon.getDate()+1);return fullMoon}
Then run getEaster(2020); // -> Sun Apr 12 2020

Convert unix timestamp to julian

How can I convert from a unix timestamp (say 1232559922) to a fractional julian date (2454853.03150).
I found a website ( http://aa.usno.navy.mil/data/docs/JulianDate.php ) that performs a similar calculation but I need to do it programatically.
Solutions can be in C/C++, python, perl, bash, etc...
The Unix epoch (zero-point) is January 1, 1970 GMT. That corresponds to the Julian day of 2440587.5
So, in pseudo-code:
function float getJulianFromUnix( int unixSecs )
{
return ( unixSecs / 86400.0 ) + 2440587.5;
}
I know that this is an old post, but I'll just say ...
The answer given by Jason Cohen is a good approximation of the conversion.
There is a problem though that relates to the number of seconds in one day. A day is not -exactly- 86400 seconds long, and periodically seconds are added to days in order to keep time synchronized with the various observable standards. These are called Leap Seconds (https://en.wikipedia.org/wiki/Leap_second). Leap seconds are added to UTC in order to keep it within 1 second of UT1.
It stands to reason that as more and more time has elapsed since Jan 1, 1970, the simple conversion above will accrue more and more error from "actual observable time." Between 1972 and 2013 there were added 25 leap seconds.
Part of the beauty and the simplicity of Julian Day numbers is that they don't represent date strings at all. They are just a count of elapsed time since the start of the Julian Epoch, much like POSIX time is a continuous count of milliseconds since the POSIX Epoch. The only problem that exists, then, is when you try to map a Julian Day number to a localized date string.
If you need a date string that is accurate to within a minute (in 2013), then you'll need an algorithm that can account for leap seconds.
Here is my JavaScript code to convert Unix timestamp to Julian. Originally is showing the current date and time, but with a little mod is answer to your question:
function computeJulianDate(DD,MM,YY,HR,MN,SC) {
with (Math) {
HR = HR + (MN / 60) + (SC/3600);
GGG = 1;
if (YY <= 1585) GGG = 0;
JD = -1 * floor(7 * (floor((MM + 9) / 12) + YY) / 4);
S = 1;
if ((MM - 9)<0) S=-1;
A = abs(MM - 9);
J1 = floor(YY + S * floor(A / 7));
J1 = -1 * floor((floor(J1 / 100) + 1) * 3 / 4);
JD = JD + floor(275 * MM / 9) + DD + (GGG * J1);
JD = JD + 1721027 + 2 * GGG + 367 * YY - 0.5;
JD = JD + (HR / 24);
}
return JD;
}
function getUTCDateTimeOrJD(now,jd=0) {
var hours = now.getUTCHours();
var minutes = now.getUTCMinutes();
var seconds = now.getUTCSeconds()
var month = now.getUTCMonth() + 1;
var day = now.getUTCDate();
var year = now.getUTCFullYear();
if (jd==1)
return computeJulianDate(month, day, year, hours, minutes, seconds);
else
return day+". "+month+". "+year+". "+hours+":"+minutes+":"+seconds;
}
var unixTime = 1473294606;
getUTCDateTimeOrJD(new Date(unixTime*1000));
getUTCDateTimeOrJD(new Date(unixTime*1000),1);
Working JSFiddle example here
This question was asked over 13 years ago as of writing. That's pretty wild. Thanks to eapo's JS formula I converted it to PineScript v5 and in testing its at least really close. I don't think perfect accuracy would even be relevant for most (if any) TradingView applications. So, I didn't go as far as to ensure perfect accuracy. But it works. Thanks eapo, you saved me a bunch of time.
EDIT: TradingView displays times in the stock/currency exchange time zone. So, it became necessary to create additional arguments to provide for the UTC offsets that exchanges utilize.
[IMPORTANT: Keep in mind that exchanges that utilize daylight savings time will shift from UTC - n to UTC - n - 1 depending on the DST state. You must update your UTC offset argument accordingly.]
// Julian Date & Partial Day in CST
computeJulianDate(dd, mm, yy, hr, mn, sc, offset=0, live=false) =>
HR = hr
HR := hr + (mn / 60) + (sc / 3600)
GGG = 1
if year <= 1585
GGG := 0
float JD = -1 * math.floor(7 * (math.floor((mm + 9) / 12) + yy) / 4)
S = 1
if ((mm - 9)<0)
S :=-1
A = math.abs(mm - 9)
J1 = math.floor(yy + S * math.floor(A / 7))
J1 := -1 * math.floor((math.floor(J1 / 100) + 1) * 3 / 4)
JD := JD + math.floor(275 * mm / 9) + dd + (GGG * J1)
JD := JD + 1721027 + 2 * GGG + 367 * yy
JD := JD + (HR / 24)
barsInSession = timeframe.isintraday ? ((24 * 60) / timeframe.multiplier) : timeframe.multiplier
barsInSession := math.floor(barsInSession) == barsInSession and timeframe.isintraday ? barsInSession - 1 : math.floor(barsInSession)
offsetInc = 1 / barsInSession
offsetCt = (offset * ((barsInSession / 24) * offsetInc))
JD := live ? JD + offsetCt : math.floor(JD - offsetCt) - 0.5
JD

Resources