Saving time in Postgres with or without TZ? - postgresql

I have a column in the DB that supposed to represent a deadline for ordering.
Let's assume the value is 11am EST.
I've saved in the DB as UTC during Winter so it was saved as 4PM UTC.
Problem is, when DST starts, the conversion back to EST was 12PM...
How can I solve this? on the DB level? if so how would I save a constant time and convert it to the correct value? If I use timestamp with TZ, will it then be read as 5PM UTC?
Thanks.

The scenario you described is caused by converting a future time to UTC and back again, using two different UTC offsets (UTC-5 and UTC-4). In general, one should not store future times (whether recurring or single-instance) in terms of UTC, unless the original reference point is already in terms of UTC. The advice "Always use UTC" applies only for past/present timestamps. It does not apply for future values.
PostgreSQL has several different date/time data types. The "with time zone" types will convert to/from UTC implicitly. The "without time zone" types will not.
In your case, it sounds like you would like to have a time-only value that describes the deadline that applies every day. Thus, you should use a time (aka time without time zone) data type for that field. You should then also store the IANA time zone ID in a separate character field (varchar(50) should be sufficient). For US Eastern Time, you would store 'America/New_York'. That assumes the cutoff is based on the same time zone for all users. If rather you are cutting it off at their time zone, then it could be different per-user, and you will need to determine the user's time zone.
When evaluating whether the deadline has passed, you would take the current UTC timestamp and convert it to the local date and time in the target time zone to have the current date and time in that zone. You'd then take a copy of that and replace the time part with your deadline time. Then compare those two values to see if the deadline has passed.
You should also be thinking about when does the deadline reset for the next day. Is it strictly based on the local date? If they try to order past that deadline, do you disallow it (and if so when do you allow it again), or does it apply to the next date? Only you can answer such questions, as it will vary based on your business needs.
The manipulations I described could be done directly in PostgreSQL, using functions like AT TIME ZONE and others, but generally you are better off doing them in your application layer. Most programming platforms have functions for manipulating dates and times, and for working with time zones.

Related

I don't know how to get timestamp in mongodb

I have a question.
When inserting or updatingOne in MongoDB, the input time is inserted using new Date().
However, when using new Date(), UTC time is recorded.
I live in Korea and I want to set the time zone to Korea.
What should I do?
You can't do that. All times in MongoDB are stored as UTC times.
Usually the client application takes care to display the time as local time. If you need to preserve the input time zone, then you must store it separately in a dedicated field.
Then you can use for example $dateToString to display the time in desired time zone.

What do you call the number of *days* since the unix epoch?

I initially learned that Unix time is the number of seconds that have elapsed since 00:00:00 (UTC) on 1 January 1970. With 24 hours in a day, that means that the unix timestamp grows by 86400 every day.
Then I heard about the concept of leap seconds, and thought that would mean that maybe on some days, the unix timestamp would grow by 86401 seconds in a day, but apparently this is not the case. From what I've read, every day is treated as if it contains exactly 86400 seconds. When you get a leap second, the operating system will 'fudge' it in some way to make sure there's still 86400 timestamps - either make every 'second' that day a little bit longer than a real SI second, or they'll report the same integer timestamp twice in a row.
So I think that this means that every date since 1 Jan 1970 can be mapped to a unique integer which is the timestamp at 00:00:00 (UTC) that day divided by 86400. (guaranteed to be an integer with no remainder because as discussed every day has to have 86400 timestamps). Alternatively you could take any timestamp during that day and calculate floor(timestamp / 86400).
For example, today, Fri 23rd April 2021 - timestamp at 00:00:00 UTC was 1619136000.
As expected, this is a multiple of 86400, and 1619136000 / 86400 = 18740.
There have been 18740 days since the unix epoch.
So my question is:
Does this integer already have a well-known name? Is it already widely used in software for representing dates? I've not been able to find any reference online to this concept.
Is my logic here correct - is there really a unique integer for each date, and you can easily calculate it in your code as timestamp_at_midnight_utc / 86400? Or is there some subtle problem that I've overlooked.
My motivation here is that I often have to do complicated calculations involving lots of dates without any time information (I work for a vacation rentals company where each unit has it's own availability calendar). I think I could make a lot of efficiency improvements in my code if I was working with integers uniquely representing a date, instead of DateTime objects, or strings like '2021-04-23'.
Yes, your logic is correct. Where I still get worried is that it requires you to do your calculations in UTC. Holiday rentals happen in a time zone, and associating a date in that time zone with the start of the day in UTC instead could get confusing soon.
And yes, the concept of a count of days since 1970-01-01 is sometimes used, though not often that I have seen.
In the Java documentation the terms “epoch day” and “epoch day count” are used, but this doesn’t make these terms a standard.
I think that the first avenue for you to consider is whether either your programming language comes with a library for counting days without the need to convert to and from seconds, or there is a trustworthy third-party library that you may use for the purpose.
This Java snippet confirms your calculation:
// A LocalDate in Java is a date without time zone or UTC offset
LocalDate date = LocalDate.of(2021, Month.APRIL, 23);
long epochDayCount = date.toEpochDay();
System.out.println("Epoch day: " + epochDayCount);
Output agrees with the result you got:
Epoch day: 18740
Link: Epoch day count in the Java documentation.
From my experience there is no official name for "days since epoch". Some nuances that can be detected about UNIX time (and its measurement units):
It appears to be (relatively) officially defined as the number of seconds since the UNIX epoch.
The main purpose of the UNIX time mechanism (regardless of measurement unit conventions) is to define a point in time.
In the context of point #2, in practice, it has already become traditional that the UNIX timestamp is often returned in milliseconds.
There are several factors that can influence the measurement unit that is available to you:
design decisions by APIs, libraries and programming languages
time resolution / clock frequency of the software & hardware that you are running on - e.g. some circuits, controllers or other entities aren't able to reach millisecond resolution or they don't have enough bits available in memory to represent big numbers.
performance reasons - offering a time service at millisecond or second resolution via HTTP might prove too much for networks / server CPUs. The next best thing would be a UNIX timestamp in minutes. This value can then be cached by intermediary caches for the duration of 1 minute.
use cases - there are epochs (e.g. in astronomy) where the day is the main measurement unit.
Here are a few examples of such day-based epochs:
The Julian Day system - which has a non-integer Julian Date (JD) but an integer Julian Day Number (JDN). Its epoch is at noon 24 November 4714 BC.
J2000 epoch - measured via Julian Date as well. Its epoch is January 1, 2000, 11:58:55.816 UTC.
If you have a look at one method of calculating the Julian Date, dividing by 86400 is an important step. So, given that the JD system seems to be widely used in astronomy, I think it would be safe to consider this division by 86400 as valid :)
This is a more complex question than you might initially realize. You want the days since 1970 to be the same for all times during the local day, and you also don't want daylight saving time changes in the local time zone and UTC date changes to affect the output.
The solution I found was to compute the seconds since 1970 in UTC but for the current local date at midnight, not the current UTC date. Here is a Linux shell script solution:
echo $(( $(date -u -d "$(date '+%Y-%m-%d') 00:00:00" '+%s') / 24 / 60 / 60 ))
date -u forces UTC time, while the second date returns the local year-month-day. This computation actually generates an integer result, even if you use a computation that supports non-integers. Computing the seconds since 1970 in local time, or using the current UTC date (and no the local day) will not work.

Unix timestamp: everywhere the same?

If I request some Unix timestamps at the same time, in any system, programming language, anywhere on the world (on universe), will they always be the same? Or is it possible that values differ?
As a precondition I assume that each system has to have their time configured correctly. Additional question: nowadays, can I assume devices with an internet connection have the correct time?
So, how reliable is the usage of the Unix timestamp? E.g. if I'd like so set an alert for different users on the world at a certain time and I broadcast just the timestamp, can I assume that the alerts happen in the same second?
(Journeys with speed of light should be disregarded here, I guess.)
Unix timestamps are the number of seconds elapsed since 01-01-1970 00:00:00 UTC so if the system time is set correctly it should be equal everywhere.

Datetime format to determine records order

we need sending some objects from database of various types within long-polling by rest. Data are sent and each record contains timestamp. When client receive new data from server he should create another poll request with record's timestamp as parameter which helps to specify following data records.
I consider about epoch unix time and store this value in each record in database to filtering and also this value will be sent with each poll requests.
What do you think about this solution? Is that usage fine or should I worry about something? Thanks.
EDIT:
I forget notice these data will be added by clients in different time-zones. This is also another reason why I consider use unix time.
Any format of storing the timestamp is fine, as long as users will be able to unambiguously interpret it. There is no reason for timestamp format in API to be the same as in database. Idea of API is to decouple model from database.
Personally I would choose one format from ISO 8601 Basic and Extended Notations. Example: 2008-09-15T15:53:00. In virtually all programing languages there are methods to handle this format (cast to unix timestamp or to internal date/time classes). For java you would use java.time.LocalDateTime#parse
Unix timestamp has some issues (they may be or not may be issues for you)
unable to represent dates before January 1st, 1970
unable to represent dates after January 19, 2038
not human-readable
does not contain timezone (timestamp itself does not have concept of timezone, but it may be useful to send client timezone along with timestamp. server may always normalise the value to UTC)

100+ dates in different timezones, calculate which 2 dates present day is between...more calculate

I am really having a heck of a time figuring out which way I should do this. Been coding objective-c for 4 months now, well trying to at least.
I have about 100+ different dates spanning 2012, down to the second, in multiple timezones. What I need is:
to grab the present time/date, see which 2 dates in my 100+ list it is between and give me time spent and time remaining.
to know which 2 dates it is between no matter what timezone a user is in.
all calculations need to take in consideration of daylight savings time. Which the dates and times of DST change is different depending on the timezone and country.
a user in Hawaii will have the same time remaining and spent as a user in England.
ablility to convert all times to local user time.
have this all realtime. have the clock or timer counting down to the second.
I have tried NSDate. Then I searched this site and found NSDateFormatter. I played with that for what seems like days. Then another search I found NSDateComponents. Do I put my 100+ dates in a multidimensional array. Do I convert everything to GMT first or can xcode do that for me. Or do I convert everytime to seconds since 1970. I am just lost on what would be the best most practical way of doing this.
Any help, thanks so much!!
I am not an iOS programmer, but if you could convert everything to the same time zone (MST, EST, GMT, whatever), then that would make your job far easier. Converting between time zones runs in constant time as there is nothing more involved than simple addition/subtraction.
As for DST, if you convert to MST or EST (as opposed to MDT or EDT), you inherently remove DST. What exactly do you mean by "take in consideration of DST?" I could help much more if you could provide that.