DST UIDatePicker issue - ios

Problem that occurs to me:
In the case of the United States where a one-hour shift occurs at
02:00 local time, in spring the clock jumps forward from the last
moment of 01:59 standard time to 03:00 DST and that day has 23 hours,
whereas in autumn the clock jumps backward from the last moment of
01:59 DST to 01:00 standard time, repeating that hour, and that day
has 25 hours.[37] A digital display of local time does not read 02:00
exactly at the shift to summer time, but instead jumps from 01:59:59.9
forward to 03:00:00.0.
And UIDatePicker is not given opportunity to set 02:00:00 time, when DST occurs. How it is possible to fix in UIDatePicker to be able to chose that time?

NSTimeZone is an abstract class that defines the behavior of time zone objects. Time zone objects represent geopolitical regions. Daylight Savings is also managed with that class. It can be done in one of the ways:
systemTimeZone:
The time zone currently used by the system. If the current time zone cannot be determined, returns the GMT time zone.
defaultTimeZone:
The default time zone for the current application. If no default time zone has been set, this method invokes systemTimeZone and returns the system time zone.
localTimeZone:
An object that forwards all messages to the default time zone for the current application. The local time zone represents the current state of the default time zone at all times.
with the localTimeZone class method, you can get a relative time zone object that decodes itself to become the default time zone on any computer on which it finds itself.

Related

Is date in the target timezone in ISO 8601?

I trying to parse a date in ISO 8601 format and some moments aren't clear for me.
For example, I have the next date: 2020-04-16T07:16:34.858215+03:00 in Europe/Moscow timezone.
Does it mean 07:16 in Moscow time or 10:16? I mean do I need to add 3 hours to date or date is in Moscow time already and timezone just shows how it diffs from UTC?
P.S. I tried to find information about it but everywhere is just common format description without details.
The time specified is the local time, so 2020-04-16T07:16:34.858215+03:00 means 7:16am in Moscow, or 4:16am UTC.
Wikipedia has a good example which clarifies things to at least some extent:
The following times all refer to the same moment: "18:30Z", "22:30+04", "1130−0700", and "15:00−03:30". Nautical time zone letters are not used with the exception of Z. To calculate UTC time one has to subtract the offset from the local time, e.g. for "15:00−03:30" do 15:00 − (−03:30) to get 18:30 UTC.
It's really unfortunate that ISO-8601 talks about this as a time zone, when it's only a UTC offset - it definitely doesn't specify the actual time zone. (So you can't tell what the local time will be one minute later, for example.)

Correct way to use moment.js to convert a series of non-UTC timestamps that cross the Fall DST boundary to UTC timestamps?

Background
I am investigating different use cases of moment.js for a project but am stumped on the issue of daylight savings ending in the fall. Before asking my question, since I want to be clear and provide background for others who have similar questions, let me explain what I am doing and what found with spring daylight savings.
First, I am working with UTC timestamps and America/New_York timestamps. In the US, daylight savings in 2017 begins on March 12 at 2AM (skipping from 2:00:00AM to 3:00:00AM) and ends on November 5 at 2AM (reverting from 2:00:00AM to 1:00:00AM). Since I also always know the target time zone (America/New_York) that I need to convert to, I will not rely upon moment.js to detect my local time zone and instead explicitly specify the time zone I want.
During the spring when daylight savings goes into effect, the time zones that observe daylight savings, like America/New_York, jump forward an hour. moment.js handles this just fine.
For example, if I pass moment.js a UTC timestamp for the time one second before daylight savings goes into effect for America/New_York, it looks like this:
moment('2017-03-12T06:59:59Z').tz('America/New_York').format('YYYY/MM/DD hh:mm:ss a z')
The input above is taken as UTC because of the Z on my timestamp and I am explicitly setting the target timezone with .tz('America/New_York') so that it doesn't use local system time.
Alternatively using moment-timezone I can explicitly set the input time zone as UTC and set the output as America/New_York.
moment.tz('2017-03-12T06:59:59', 'UTC').tz('America/New_York').format('YYYY/MM/DD hh:mm:ss a z')
Either way, the result is 2017/03/12 01:59:59 am EST.
Then, I run the same commands for a moment just one second later. I will just use the format given in the first example above where I specify the time as UTC and then convert it to America/New_York time:
moment('2017-03-12T07:00:00Z').tz('America/New_York').format('YYYY/MM/DD hh:mm:ss a z')
And my result is correct as expected: 2017/03/12 03:00:00 am EDT - due to daylight savings the time skipped ahead by one hour.
I can then use moment-timezone to go back the other way by passing in an America/New_York timestamp and converting it to UTC.
moment.tz('2017-03-12T01:59:59', 'America/New_York').utc().format('YYYY/MM/DD hh:mm:ss a z')
This gives me 2017/03/12 06:59:59 am UTC
And the next moment in the America/New_York time zone, because of daylight savings coming into play, is 03:00:00 so I convert that to UTC...
moment.tz('2017-03-12T03:00:00', 'America/New_York').utc().format('YYYY/MM/DD hh:mm:ss a z')
... and get 2017/03/12 07:00:00 am UTC which looks correct.
An hour was skipped ("lost") in America/New_York time, but moment can detect that and convert it to UTC.
In Summary, for the spring daylight savings change in the US, I can pass a UTC timestamp into either moment.js or moment-timezone and get back a timestamp in another time zone with the correct daylight savings offset also applied. I can also then pass an America/New_York timestamp into moment and get back a correctly converted UTC timestamp.
My Question
Great, so I want to do the same thing when daylight savings ends in the fall and of course it isn't that simple. My hypothesis is that due to daylight savings effectively causing an hour to "repeat", there is no way for moment to know the correct time UTC. In other words, where there was a gap of one hour when daylight savings started, now we have overlap of one hour.
Question (part 1): Is there a way to pass a relative timestamp and time zone into moment and get back the correct UTC time? When I tried this in the examples below, moment skips an hour on the UTC side.
moment.tz('2017-11-05T01:00:00', 'America/Denver').tz('UTC').format('YYYY/MM/DD hh:mm:ss a z') => "2017/11/05 07:00:00 am UTC"
moment.tz('2017-11-05T01:59:59', 'America/Denver').tz('UTC').format('YYYY/MM/DD hh:mm:ss a z') => "2017/11/05 07:59:59 am UTC"
moment.tz('2017-11-05T02:00:00', 'America/Denver').tz('UTC').format('YYYY/MM/DD hh:mm:ss a z') => "2017/11/05 09:00:00 am UTC"
moment.tz('2017-11-05T02:59:59', 'America/Denver').tz('UTC').format('YYYY/MM/DD hh:mm:ss a z') => "2017/11/05 09:59:59 am UTC"
I assume its because time is happening chronologically like in the example below. UTC offset context is not given therefore I assume that moment cant distinguish between the America/New_York timestamps preceded by asterisks:
*2017/11/05 01:00:00 am America/New_York => 2017/11/05 07:00:00 am UTC
*2017/11/05 01:59:59 am America/New_York => 2017/11/05 07:59:59 am UTC
*2017/11/05 01:00:00 am America/New_York => ???
*2017/11/05 01:59:59 am America/New_York => ???
2017/11/05 02:00:00 am America/New_York => 2017/11/05 09:00:00 am UTC
2017/11/05 02:59:59 am America/New_York => 2017/11/05 09:59:59 am UTC
Again, what I want to know is if there is a way around this? Currently the timestamps in the data that I have does not contain UTC offsets.
Question (part 2): If I am presenting data in the America/New_York time zone then is it correct to think that I will essentially have two hours of data points all stuffed into a (seemingly) single one hour period from 01:00:00 to 01:59:59 on November 5, 2017?
Related Topics
There are a few other topics on SO that are related to this but none that I have found pose or answer this same question. I will link a few here for reference:
Moment.js Convert Local time to UTC time does work
Initialize a Moment with the timezone offset that I created it with
It looks like you have thought the problem through and done some basic research. Thanks!
What you are describing is covered in the moment-timezone docs here. If the data isn't available as a UTC offset in your input, there's no way to tell the difference between the first or second occurrence of an ambiguous local time. Moment picks the first occurrence, because time moves in a forward direction, so this is usually the most sensible choice for most scenarios.
The problem is one of ambiguity. Even as just a human being, if I say "1:00 am on November 5th 2017 in New York" you don't know which of two points in time I'm describing.
That said, sometimes you have external knowledge that can help. For example, if you have an ordered set of timestamps containing time that skips backwards, then you know you encountered a fall-back transition. Say I'm recording data at 15 minute intervals in local time:
00:45
01:00
01:15
01:30
01:45
01:00 <--- this one comes next sequentially, but appears backwards, so infer transition
01:15
01:30
01:45
02:00
You'll have to write your own detection logic to compare one value to the next for that scenario. Also note that if you don't have any time that appears to be out of sequence, then you cannot be assured of which occurrence is being described. A "heartbeat" signal can assist with this in some scenarios.
Now how do you choose the second occurrence in Moment without knowing the offsets in advance? Like this:
First, grab the hasAmbiguousWallTime function from here.
Then define another function:
function adjustToLaterWhenAmbiguous(m) {
if (hasAmbiguousWallTime(m)) {
m.utcOffset(moment(m).add(1, 'hour').utcOffset(), true);
}
}
Now you can do this:
// start with the first occurrence
var m = moment.tz("2017-11-05T01:00:00", "America/New_York");
m.format(); // "2017-11-05T01:00:00-04:00"
// now shift it to the second occurrence
if (... your logic, such as wall time going backwards in sequence, etc. ...) {
adjustToLaterWhenAmbiguous(m);
m.format(); // "2017-11-05T01:00:00-05:00"
}
These two functions should probably be hardened and added to moment-timezone, but they should be sufficient for the scenario you describe.
A couple of other minor points:
Instead of moment.tz(s, 'UTC'), consider using moment.utc(s)
Instead of moment.tz(s, 'America/New_York').tz('UTC'), consider
using moment.tz(s, 'America/New_York').utc()
You may want to review the DST tag wiki for visualization of the problem space.
On part two of your question, yes - you'll end up stuffing two hours of data into what could possibly be visualized as a one-hour space. People have this problem with graphs and charts all the time. They graph something with a constant value over local time, then see a zeroing effect in the spring, and a doubling effect in the fall. Even if you tell moment to use the later occurrence, you won't avoid this unless you actually display the graph in UTC instead of local time.

Daylight to Standard timezone conversion in iOS

Some countries are observing daylight saving, but I want to get the timezone name irrespective of daylight saving.
In short I want standard time of such countries instead of daylight saving time.
Is there any way to convert this or anything else?
P.S. I want this because of my server requirement.
//----------------------------------------------------------------
I have seen this reference in apple.
+ (instancetype)timeZoneForSecondsFromGMT:(NSInteger)seconds
Discussion The name of the new time zone is GMT +/– the offset, in
hours and minutes. Time zones created with this method never have
daylight savings, and the offset is constant no matter the date.
But I wonder how it will useful to me for my problem? As I want timezone name without daylight saving not any time with offset.
If you just need the time zone with respect to GMT without accounting for DST, the simplest option would be to:
Find the DST offset using 'daylightSavingTimeOffset' on your suspect time zone.
Subtract that value from the timezone's GMT offset.
Create a new time zone with the now adjusted offset.
If you need the name of the standard time zone, the simplest approach might just be to look for "DST" and "Daylight" in the time zone description and then pick the time zone that has the greatest number of words matching to the DST time zone. That might not be the most elegant solution, but it would work for most time zones.
It was actually this
typedef enum : NSInteger {
NSTimeZoneNameStyleStandard,
NSTimeZoneNameStyleShortStandard,
NSTimeZoneNameStyleDaylightSaving,
NSTimeZoneNameStyleShortDaylightSaving,
NSTimeZoneNameStyleGeneric,
NSTimeZoneNameStyleShortGeneric
} NSTimeZoneNameStyle;
The enum answered it for me. My bad , I should have read this earlier.

Do UNIX timestamps change across timezones?

As the subject asks; do UNIX timestamps change in each timezone?
For example, if I sent a request to another email the other side of the world saying, "Send out an email when the time is 1397484936", would the other server's timestamp be 12 hours behind my own?
The definition of UNIX timestamp is time zone independent. The UNIX timestamp is the number of seconds (or milliseconds) elapsed since an absolute point in time, midnight of Jan 1 1970 in UTC time. (UTC is Greenwich Mean Time without Daylight Savings time adjustments.)
Regardless of your time zone, the UNIX timestamp represents a moment that is the same everywhere. Of course you can convert back and forth to a local time zone representation (time 1397484936 is such-and-such local time in New York, or some other local time in Djakarta) if you want.
The article at http://en.wikipedia.org/wiki/Unix_time is pretty impressive if you'd like a longer read.
Unix time is defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970. So the answer is no
Unix timestamps do not change accross timezones, they are created for the purpose of having a standard time across globe.
NOTE:-
Timestamps are calculated on the basis of current time in the computer thus do not rely on them until and unless you are very sure about the time settings in the participating machines.
Someone stated that "UTC is Greenwich Mean Time without Daylight Savings time adjustments." This is simply untrue. GMT does not have Dayllight Savings Time. GMT is measured in Greenwich, England (at the Naval Obeservatory) [0 longitude, but not 0 lattitude]. UTC is measured at the equator [0 longitude and 0 lattitude - which happens to lie in the ocean off the cost of Africa].
What difference does it make? It doesn't make a difference in terms of "what time of day is it?" It does, however, make a difference in terms of calculating a year. Now you'd think a year would be measured based upon the location of the center (the core) of the earth, right? When the earth's core is back in the same location it was ~365 days ago, it has been a year. It isn't measured that way. It is measured by a specific location on the earth getting back to the same location (relative to the sun) that it was ~365 days ago. But the period of a day and a year don't divide evenly. Once the earth is back to about where it was a year ago, the earth isn't facing the same direction it was last year, so that spot on the earth isn't facing the same direction it was a year ago. Being further north, Greenwich isn't going to get back to the same spot (relative to the sun) that it was last year at the same time that 0 Lat / 0 Long is. So if you base the definition on Greenwith vs. 0/0, you get a, albeit slightly, different answer to the question "how many days are in a year". To put it another way, when a given spot on the earth gets back to where it was a year ago (relative to the Sun), the core of the earth isn't in the same spot it was a year ago, so what spot you pick matters because the core of the earth is going to be in a different spot (relative to the sun) than it was one year ago, if you pick a different spot on the earth.
Neither UTC nor GMT have daylight savings time. Europe/London time, the timezone that Greenwich resides in, does. But GMT does not. GMT is, what Americans would call a "Standard Time" - i.e. without DST.
Getting back to the question, Epoch time doesn't technically have a timezone. It is based on a particular point in time, which just so happens to line up to an "even" UTC time (at the exact beginning of a year and a decade, etc.). If that concept doesn't fit well in your brain, and if it helps to think of Epoch time as being in UTC, go right ahead. You're in good company and in the grand scheme of things, it really doesn't matter. You ever see those law suits where somoene is awarded $1. It's kind of a "you're right, but it doesn't really matter" type of verdict. If someone sued you for saying Epoch time is in the UTC timezone, they would win $1. That wouldn't buy them a cup of coffee at any Starbucks in any timezone on the planet.
IF both computers are set up correctly with their clocks set for the correct timezone and UTC values, they should return the same value.
Of course that's a big IF. There's almost certain to be a difference of at least a second, more often minutes between the time reported by two computers. And many computers are set up to have incorrect timezone settings, and will report their local time when asked a timestamp rather than UTC.
And in that lies the difference between theory and practice. In theory it's all the same, in practice you should not rely on it.
No, epoch timestamp should not change, because it has a fixed timezone which is UTC.
If you want to use a time object in other time zone, just look it up in libraries of the language you use, but do NOT try to add/substract a couple of hours from epoch timestamp and assume it's in another time zone, which will make things very confusing to other people, especially when you expose it in your API.
If you use C++, I recommend this library. I heard it will soon be added into standard library.
For all, I understand sometimes time object is hard to deal with and it looks easier to add/substruct on epoch timestamp. Please don't do it and do not persuade others to do it. A time object is much easier once you get used to it and can take care of time zone conversion easily without messing up with historical time zone changes due to politics/law etc...

XQuery - determine whether a given UTC time falls in daylight saving time in a given timezone

In XQuery, how can I determine whether a UTC time falls within daylight saving time in a region?
Something like:
declare function local:IsDaylightSavingTime($utcDateTime as xs:utcDateTime, timeZone xs:dayTimeDuration) as xs:boolean {
...
}
This is not possible.
How would you expect a time zone to be represented by an xs:dayTimeDuration? That would assume a time zone is the same thing as a time zone offset, which it is not. Please read the timezone tag wiki.
Besides, any program that is capable of performing this function needs some type of time zone database. While it is conceivable that a particular XQuery implementation decided to incorporate a time zone database, that certainly wouldn't be in the XQuery language itself.

Resources