💾 Archived View for bbs.geminispace.org › u › jeang3nie › 5193 captured on 2024-08-25 at 07:14:33. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2024-08-18)

🚧 View Differences

-=-=-=-=-=-=-

Comment by 🦀 jeang3nie

Re: "Converting Unix timestamp to date/time"

In: s/programming

Ok, give me a few minutes. I'm going through the code now to get it working with Zig 0.11, and then I'll push it to codeberg instead of my home server.

🦀 jeang3nie

2023-09-10 · 1 year ago

7 Later Comments ↓

🦀 jeang3nie · 2023-09-10 at 22:58:

I guess I posted the link incorrectly the first time. I fixed it, but I also mirrored the code on Codeberg.

— https://codeberg.org/jeang3nie/zig-chrono

You've got the right idea with what you described so far. There's a few things you have to account for that are a little sticky.

Calculating leap years is slightly more complex than I realized. When growing up I thought it was just every four years, but that would slowly skew the seasons. The year must be divisible by 4, but not 100, unless it is also divisible by 400. How's that for fun?

So we know that we have 24 hours in a day, 60 minutes in an hour, and 60 seconds in a minute. From that we can derive a constant seconds per day = 24 * 60 * 60. We start at the unix epoch 1/1/1970 which corresponds to 0 seconds and increment the year (assuming a positive timestamp), adding the number of seconds in that year (364 * secs/year or 365 * secs/year if a leap year), until the result would go past the timestamp we want to convert. At that point we know what year the timestamp falls in. From there, we do the same for months but we're looking at seconds per month, which varies depending on what month it is, and in the case of February also whether it's a leap year or not. Then on to days, hours, minutes and seconds. It's just basically a big iterator.

The conversion happens in the function DateTime.fromTimestamp.

— https://codeberg.org/jeang3nie/zig-chrono/src/commit/2d2b99c954d21edd5a75f597014ec15ce6042065/src/main.zig#L86

I realized after my first reply that the post I had been working on was for my big web blog, so it's nowhere near in shape for gemini. But I can walk you through any parts that are unclear. I did this implementation because I had already done it in Rust for my Misfin project and found it interesting enough for a blog post, so I've implemented it twice now. Pretty sure I could translate it into a few other languages without much trouble.

🦀 jeang3nie · 2023-09-10 at 23:03:

Also, about leap seconds. The big takeaway is that so long as you are working in a hosted environment (your code is running within an operating system and getting it's time from what the OS says is system time) you can ignore leap seconds, because the OS handles it for you. The usual method is that if a year is supposed to get a leap second, the final second of the year just gets repeated. So on Dec 31st of that year you'll get two seconds which have the same timestamp. It's not perfect but it's the convention, and it has the benefit that as a programmer you just don't have to care unless you're working on kernel code.

Of course, in true asshole fashion, both Google and Meta decided to get fancy and in their systems they smeared the extra second out over all of the seconds in the day the past couple times it came up. Because why care about interopability?

Sorry for the long windedness, I just find the subject fascinating.

🚀 stack [OP] · 2023-09-11 at 01:48:

Interesting. It seems like my way is a lot easier. Since the only weird year between 1970 and 2037 is 2000, and it happens to be a leap year, we can ignore the 100/400-year exception - it is just like the rest of the leap years. I already have days since 1970, so I can continue the calculation in days.

As noted previously, I adjust to March 1972 as the base year, to shift the leap day to the last day of a 4-year bundle. I can then divide by the number of days in such bundles, yielding number of days within the final quad as remainder.

The rest of the calculation is division by 365 to find the year within a quad (which also detects if we won the leap year lottery),

Then, to figure out the months, I go into a loop subtracting days in each month. That is the only iteration required.

🚀 mbays · 2023-09-11 at 05:30:

So you plan to be part of the Y2038 problem?

🐉 gyaradong · 2023-09-11 at 06:43:

some notes:

- a country went into daylight savings and never came out

- countries and states routinely change the dates when coming into or out of daylight savings.

- a country one skipped a week or rewound a week. can't remember which.

- a small island went from one side of the international date line to the other. I think they are now beyond 12 hours forward.

I'm never touching a time library.

🦀 jeang3nie · 2023-09-11 at 15:03:

Crap, don't get me started on daylight savings time.

🚀 stack [OP] · 2023-09-11 at 17:05:

I am passing the buck to the user, of course. A variable will keep the timezone adjustment offset, and whoever cares about this will set it to the right amount.

At this point, it is very likely that I will be the only user anyway.

X

Original Post

🌒 s/programming

Converting Unix timestamp to date/time — Without any outside libraries. All we have is a Unix timestamp, seconds since Jan. 1, 1970. I'm looking for a minimalistic solution for my tiny nForth, but really curious if anyone has tricks up their sleeve for this kind of a task. I'm willing to ignore leap seconds for now. So far I got the time part: add timezone in seconds, divide by 86400 to get days, and use the remainder for time in seconds. The rest is trivial, dividing by 60 for minutes and 60...

💬 stack · 10 comments · 1 like · 2023-09-10 · 1 year ago