About Monkey 2 › Forums › Monkey 2 Programming Help › Convert seconds to Time()
This topic contains 16 replies, has 4 voices, and was last updated by
Angus 9 months, 3 weeks ago.
-
AuthorPosts
-
June 30, 2018 at 8:58 pm #14950
Hello,
I feel like I am missing something pretty obvious here, but how can I convert the long return from GetFileTime into a new Time instance? Specifically I am looking to have the time formatted.
I thought that maybe I can pass the seconds into new Time() but that does not work…
</p><p>local seconds := GetFileTime("myfile.txt")<br />Print new Time(0, 0, 0, 0, 0, seconds) ' Wed 31 Dec 1969 17:59:59</p><p>
Thank you
July 1, 2018 at 6:17 am #14952This is a problem I relegated to “think about later” last year when I made my file requester and I still have it on that pile. Searching around I found this thread:
https://www.avrfreaks.net/forum/converting-unix-time-date-stamp-human-readable-form
In the fifth post david.prentice posts this code, which apparently works, but is it exactly what you’re looking for? It seems to be what I’m after. It doesn’t look hard to convert.. (?)
struct tm *gmtime(timep) const time_t *timep;
{
static struct tm tmbuf;
register struct tm *tp = &tmbuf;
time_t time = *timep;
register long day, mins, secs, year, leap;
day = time/(24L*60*60);
secs = time % (24L*60*60);
tp->tm_sec = secs % 60;
mins = secs / 60;
tp->tm_hour = mins / 60;
tp->tm_min = mins % 60;
tp->tm_wday = (day + 4) % 7;
year = (((day * 4) + 2)/1461);
tp->tm_year = year + 70;
leap = !(tp->tm_year & 3);
day -= ((year * 1461) + 1) / 4;
tp->tm_yday = day;
day += (day > 58 + leap) ? ((leap) ? 1 : 2) : 0;
tp->tm_mon = ((day * 12) + 6)/367;
tp->tm_mday = day + 1 – ((tp->tm_mon * 367) + 5)/12;
tp->tm_isdst = 0;
return (tp);
}The Mod keyword is reserved in M2, but I can’t actually find the command. Apparently % is mod? I know nothing about… C? (ignorance!)
I have to go and do other work, but I’m going to try to convert it myself later today.
July 1, 2018 at 9:32 am #14953Mod just works as expected here:
Monkey1Print 13 Mod 10gives you 3 as output
July 1, 2018 at 1:27 pm #14954Thanks! So I’m pretty unsure what I’m doing, and what it’s doing isn’t quite right, but I bet I’m making a simple error:
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253'struct tm *gmtime(timep) const time_t *timep;'{' static struct tm tmbuf;' register struct tm *tp = &tmbuf;' time_t time = *timep;' register long day, mins, secs, year, leap;' day = time/(24L*60*60);' secs = time % (24L*60*60);' tp->tm_sec = secs % 60;' mins = secs / 60;' tp->tm_hour = mins / 60;' tp->tm_min = mins % 60;' tp->tm_wday = (day + 4) % 7;' year = (((day * 4) + 2)/1461);' tp->tm_year = year + 70;' leap = !(tp->tm_year & 3);' day -= ((year * 1461) + 1) / 4;' tp->tm_yday = day;' day += (day > 58 + leap) ? ((leap) ? 1 : 2) : 0;' tp->tm_mon = ((day * 12) + 6)/367;' tp->tm_mday = day + 1 - ((tp->tm_mon * 367) + 5)/12;' tp->tm_isdst = 0;' return (tp);'}Function TimeToString:String(ut:ULong)Local day:ULong,mins:ULong,secs:ULong,year:ULong,leap:ULongLocal tf:ULong=24day=ut/(tf*60*60)secs=ut Mod (tf*60*60)Local oSecond:ULong=secs Mod 60mins=secs/60Local oHour:ULong=mins/60Local oMinute:ULong=mins Mod 60Local oWeekDay:ULong=(day+4) Mod 7year=(((day*4)+2)/1461)Local oYear:ULong=year+70leap=Not(oYear & ULong(3))day-=((year*1461)+1)/4Local oYearDay:ULong=dayIf day>58 Or leapIf leapday+=1Elseday+=2EndElseday+=0EndLocal oMonth:ULong=((day*12)+6)/367Local oMonthDay:ULong=day+1-((oMonth*367)+5)/12Local oISDST:ULong=0Return String(oMonthDay)+" of month:"+String(oMonth)+" of year:"+String(oYear)+" Hour:"+String(oHour)+" Minute:"+String(oMinute)+" Second:"+String(oSecond)+" Day of week:"+String(oWeekDay)EndIt produces this output when provided with the time value for the bit of code that contains it (so should be bang on compile time)
1 of month:6 of year:118 Hour:13 Minute:18 Second:0 Day of week:0
Which is nearly right in a lot of ways. It is the first of the seventh month of 2018 (only 1900 years out) and it’s 14 hours n 18 minutes etc. The hours value being one hour out could be down to UK daylight savings?
Edit… the above description is of how accurate it was. Is that obvious lol?
What’s the obvious error I’m making? I guess this:
leap=Not(oYear & ULong(3))
produces something wrong because oYear is of the wrong class. I’m not sure what the class of the variable in the example are.
I realise you may want a different sort of output to this, but if someone knows what I’m doing wrong it looks like this could be modified to provide the correct date n time however you want it.
July 1, 2018 at 1:54 pm #14955Well this probably makes more sense, given the output of the filetime function, but it’s still the same…
Monkey1234567891011121314151617181920212223242526272829Function TimeToString:String(ut:Long)Local day:Long,mins:Long,secs:Long,year:Long,leap:LongLocal tf:Long=24day=ut/(tf*60*60)secs=ut Mod (tf*60*60)Local oSecond:Long=secs Mod 60mins=secs/60Local oHour:Long=mins/60Local oMinute:Long=mins Mod 60Local oWeekDay:Long=(day+4) Mod 7year=(((day*4)+2)/1461)Local oYear:Long=year+70leap=Not(oYear & Long(3))day-=((year*1461)+1)/4Local oYearDay:Long=dayIf day>58 Or leapIf leapday+=1Elseday+=2EndElseday+=0EndLocal oMonth:Long=((day*12)+6)/367Local oMonthDay:Long=day+1-((oMonth*367)+5)/12Local oISDST:Long=0Return String(oMonthDay)+" of month:"+String(oMonth)+" of year:"+String(oYear)+" Hour:"+String(oHour)+" Minute:"+String(oMinute)+" Second:"+String(oSecond)+" Day of week:"+String(oWeekDay)EndBut trying it with some other files, it’s really close to being right. Looks like the month is one unit too early (annoying) and the year is out (very annoying), but the day of the month and the day of the week and the time all seem right… a file in January reports the correct time, suggesting it doesn’t compensate for daylight savings.
July 1, 2018 at 2:05 pm #14956The more I play with this the more I think I’ll just fudge it myself to add one to the month at the last minute and 1900 to the years.
I guess I could do some things to make daylight savings correct as well, but that’s more annoying. Everything else seems ok, including the day. 0-sunday 1-monday etc… I looked at some files for last year and they were correct, or at least predictably incorrect.
I’d rather have an error I’m making pointed out tho, I trust his code more than my fudges and still suspect I made a mistake.
I’ll post what I’m going to end up using if no-one can see an error.
July 1, 2018 at 3:19 pm #14957I figured out my silly mistakes and this is the code as I’ll use it. I made it this way as I imagine rattling through potentially thousands of files and having to make names for each…
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344Class UnixTimeGlobal dayName:String[]=New String[]("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")Global monthName:String[]=New String[]("January","February","March","April","May","June","July","August","September","October","November","December")Global suffix:String[]=New String[]("zeroth","st","nd","rd","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","st","nd","rd","th","th","th","th","th","th","th","st")Function ToString:String(ut:Long)Local day:Long,mins:Long,secs:Long,year:Long,leap:LongLocal tf:Long=24,t:Long=3day=ut/(tf*60*60)secs=ut Mod (tf*60*60)Local oSecond:Long=secs Mod 60mins=secs/60Local oHour:Long=mins/60Local oMinute:Long=mins Mod 60Local oWeekDay:Long=(day+4) Mod 7year=(((day*4)+2)/1461)Local oYear:Long=year+70leap=Not(oYear & 3)day-=((year*1461)+1)/4Local oYearDay:Long=dayIf day>(58+leap)If leapday+=1Elseday+=2EndElseday+=0EndLocal oMonth:Long=((day*12)+6)/367Local oMonthDay:Long=day+1-((oMonth*367)+5)/12Local oISDST:Long=0oYear+=1900Return dayName[oWeekDay]+", "+String(oMonthDay)+suffix[oMonthDay]+" "+monthName[oMonth]+" "+String(oYear)+" "+String(oHour)+":"+String(oMinute)+":"+String(oSecond)EndEndSo if I say:
Print UnixTime.ToString(1364485543)
it outputs:
Thursday, 28th March 2013 15:45:43
I tested it a fair bit and it seems ok, but perhaps I’m still making a mistake. Using the same logic you could make it convert to different things.
July 1, 2018 at 3:23 pm #14958In fact looking at it again, having gone to the trouble to structure it that way, I may remove the local variables all together and make them permanent globals to work with. Would I just be wasting my time? I’m not sure…
July 1, 2018 at 3:40 pm #14959I did that, and made a couple of other small changes, and I guess this is what I’ll use…
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344Class UnixTimeGlobal dayName:String[]=New String[]("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")Global monthName:String[]=New String[]("January","February","March","April","May","June","July","August","September","October","November","December")Global suffix:String[]=New String[]("th","st","nd","rd","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","st","nd","rd","th","th","th","th","th","th","th","st")Global day:Long,mins:Long,secs:Long,year:Long,leap:LongGlobal tf:Long=24Global oSecond:Long,oHour:Long,oMinute:Long,oWeekDay:Long,oYear:Long,oYearDay:Long,oMonth:Long,oMonthDay:LongFunction ToString:String(ut:Long)day=ut/(tf*60*60)secs=ut Mod (tf*60*60)oSecond=secs Mod 60mins=secs/60oHour=mins/60oMinute=mins Mod 60oWeekDay=(day+4) Mod 7year=(((day*4)+2)/1461)oYear=year+70leap=Not(oYear & 3)day-=((year*1461)+1)/4oYearDay=dayIf day>(58+leap)If leapday+=1Elseday+=2EndElseday+=0EndoMonth=((day*12)+6)/367oMonthDay=day+1-((oMonth*367)+5)/12oYear+=1900Return dayName[oWeekDay]+", "+String(oMonthDay)+suffix[oMonthDay]+" "+monthName[oMonth]+" "+String(oYear)+" "+String(oHour)+":"+String(oMinute)+":"+String(oSecond)EndEndIf there aren’t any other functions to do this, I could add it in the code library. Are there things about the way I did it that make it unsuitable?
July 1, 2018 at 3:53 pm #14960Hmmm I’m so prone to tweaking. Actually the code I’m going to use is more like this, as it makes vaguely more sense.
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344Class StringTimeGlobal dayName:String[]=New String[]("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")Global monthName:String[]=New String[]("January","February","March","April","May","June","July","August","September","October","November","December")Global suffix:String[]=New String[]("th","st","nd","rd","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","st","nd","rd","th","th","th","th","th","th","th","st")Global day:Long,mins:Long,secs:Long,year:Long,leap:LongGlobal tf:Long=24Global oSecond:Long,oHour:Long,oMinute:Long,oWeekDay:Long,oYear:Long,oYearDay:Long,oMonth:Long,oMonthDay:LongFunction FromUnix:String(ut:Long)day=ut/(tf*60*60)secs=ut Mod (tf*60*60)oSecond=secs Mod 60mins=secs/60oHour=mins/60oMinute=mins Mod 60oWeekDay=(day+4) Mod 7year=(((day*4)+2)/1461)oYear=year+70leap=Not(oYear & 3)day-=((year*1461)+1)/4oYearDay=dayIf day>(58+leap)If leapday+=1Elseday+=2EndElseday+=0EndoMonth=((day*12)+6)/367oMonthDay=day+1-((oMonth*367)+5)/12oYear+=1900Return dayName[oWeekDay]+", "+String(oMonthDay)+suffix[oMonthDay]+" "+monthName[oMonth]+" "+String(oYear)+", "+String(oHour)+":"+String(oMinute)+":"+String(oSecond)EndEnd
I’m gonna stop playing with this and go back to other thingsJuly 1, 2018 at 4:31 pm #14961Haha wow Angus, thank you.
Here’s my version of what you made
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465Function Main()Local fileTime := GetFileTime(AppDir()+ "app.json")Print fileTimeLocal st := New StringTime(fileTime)Local str:String = stPrint "string:" +strLocal time:Time = stPrint "time:" +timeEndClass StringTimeGlobal dayName:String[]=New String[]("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")Global monthName:String[]=New String[]("January","February","March","April","May","June","July","August","September","October","November","December")Global suffix:String[]=New String[]("th","st","nd","rd","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","st","nd","rd","th","th","th","th","th","th","th","st")Global tf:Long=24Field day:Long,mins:Long,secs:Long,year:Long,leap:LongField oSecond:Long,oHour:Long,oMinute:Long,oWeekDay:Long,oYear:Long,oYearDay:Long,oMonth:Long,oMonthDay:LongMethod New(ut:Long)day=ut/(tf*60*60)secs=ut Mod (tf*60*60)oSecond=secs Mod 60mins=secs/60oHour=mins/60oMinute=mins Mod 60oWeekDay=(day+4) Mod 7year=(((day*4)+2)/1461)oYear=year+70leap=Not(oYear & 3)day-=((year*1461)+1)/4oYearDay=dayIf day>(58+leap)If leapday+=1Elseday+=2EndElseday+=0EndoMonth=((day*12)+6)/367oMonthDay=day+1-((oMonth*367)+5)/12oYear+=1900EndMethod To:String()Return dayName[oWeekDay]+", "+String(oMonthDay)+suffix[oMonthDay]+" "+monthName[oMonth]+" "+String(oYear)+", "+String(oHour)+":"+String(oMinute)+":"+String(oSecond)EndMethod To:Time()Return New Time(oMonthDay, oMonth, oYear, oHour, oMinute, oSecond)EndEndJuly 1, 2018 at 4:35 pm #14962Sweet little change!
July 1, 2018 at 4:38 pm #14963Hmm as I think about this, though, I’m sure it’ll have a problem with dates before 2000. Like I say the doubts I had were correct in that they were with how I was interpreting what he was doing. The month, for example is correct if January=0, as it does when being read from an array. Worth bearing in mind when displaying the month as a number.
So I suspect a further look at how I made his code into M2 code would be worth it, I’m not too sure about where I might be making an error. Frustrating as it’s really close, and it’s fun to see words appear out of that opaque looking number.
July 1, 2018 at 5:36 pm #14964Can’t check it just now, but will soon. I’ll need this to work myself so I’ll have to keep coming back til it does
July 1, 2018 at 10:44 pm #14966OK, I’ve just added Time.FromFileTime:Time( fileTime:long ) which can simply be passed a GetFileTime() time, eg:
Local time:=Time.FromFileTime( GetFileTime( filePath ) )
Now up in develop branch.
-
AuthorPosts
You must be logged in to reply to this topic.