Getting List of Timezones in xcode - iphone

I am able to get list of timezones using
NSArray *timezoneNames = [NSTimeZone knownTimeZoneNames] ;
The issue is that the list is generated based on the current date set on device. I want this list to be generated using a future date, so that it correctly reflects the applicable Daylight Saving Offset.
e.g. If I use the APP in May 2012 the timezone entry for Chicago is
America/Chicago (CDT) Offset -18000 (Daylight)
and if I use the same APP in February 2012 the entry for Chicago is
America/Chicago (CST) Offset -21600
Can I change the System date within my code so that I can generate the list for any particular date at will?
Sanjay

Related

How to fix incorrect Date due to timezone in Core Data from using Calendar.current.startOfDay?

I have erroneously used Calendar.current.startOfDay(for: Date()) to populate a date attribute in Core Data. This means that when users cross different timezones I may have different dates unintentially stored in the date attribute field e.g.
Timezone 1 - 25th 23:00
Timezone 2 - 25th 22:00
Timezone 3 - 26th 05:00
I need to update the Calendar to use UTC Timezone but I need to also perform a migration so that the existing entries in Core Data read like this…
Result:
Timezone 1 - 26th 00:00
Timezone 2 - 26th 00:00
Timezone 3 - 26th 00:00
What are the steps to perform this migration. If I do a UTC startOfDay on it Timezone 1 would get 25th 00:00 instead of 26th 0:00 which is what it should be. Is it possible to accurately update existing entries?
Edit:
For some context I need a reliable way to get all the entries for the 26th for example. I used startOfDay to store the date as it meant I could query by it too and have the relevant entry returned (at any moment in time get the startOfDay and it will give me the entries for the whole day). For historical dates I can do the same - let's say the user has navigated back 2 days I can take startOfDay and subtract 2 days using Calendar.current.date(byAdding: .day, value: -2, to: date) and query for that.
So now the timezone breaks the above logic but is there some way to fix this? If I loop through the entries I can figure out the date it was supposed to be for and perhaps change the attribute to a string - e.g. 26-05-2021 or start to store day, month, year instead and query that.
From reading your answer Duncan I don't think I want to use UTC calendar as it would start to store the entry against the incorrect date from the users perspective dependent on their timezone e.g. user moves to next day and utc is still on previous.
Edit 2:
In a migration I will take the date that is stored and map it to new day, month and year properties storing those instead by getting them from Calendar.current.dateComponents([.day, .month, .year], from: date). Then instead of query by date I will query by day month and year of the Calendar.current where the user is. The side effect here is there is potential the user adds something for today (27th) changes timezone and sees 26th data but I don't think it can be avoided and the old data will then show as intended.
If you took the current time and used Calendar.current.startOfDay(for: Date()) to calculate midnight in the user's local time zone, you have a loss of information. You don't know what time of day the operation was performed. If you saved the time of day in the local time zone in another field, you could reconstruct a Date in UTC.
It isn't clear that what you did was wrong. The day, month, and year is only meaningful in a specific time zone. I am in the Washington DC metro area. We are in daylight savings time (EDT). It is currently 20:56 on the 26th of May. However, it's 1:56 AM on the 27th of May in London, 2:57 AM in Munich, and 3:57 AM in Tel Aviv. All at the exact same instant in time. In UTC it is 0:57 AM on the 27th of May.
Most people think of the calendar date in their local time zone. That is their frame of reference. If you ask me the date right now, I'll tell you it's the evening of the 26th of May. Unless I know you are in a different time zone, that's the "right" answer to me.
If I start out at midnight on a given day in my time zone, calling Calendar.current.startOfDay(for: Date()) each hour, I'll get midnight that day for all 24 hours in my local time zone. For the first 20 hours of the day, that would be the same result I would get if I created a Calendar in UTC and made the same call. However, at 20:00 EDT, I would start getting the next calendar day if I made the same query in UTC.
If you don't know what time of day you made the call to Calendar.current.startOfDay(for: Date()), there is no foolproof to figure out the day/month year in UTC at the instant you made the call. It depends on the time of day in the local timezone, and that timezone's offset from UTC.
Consider this code:
var calendarUTC = Calendar(identifier: .gregorian)
if let utcTimeZone = TimeZone(identifier: "UTC") {
print("Valid time zone")
calendarUTC.timeZone = utcTimeZone
}
print ("Start of day in UTC is \(calendarUTC.startOfDay(for: Date()))")
print ("Start of day in local time zone is \(Calendar.current.startOfDay(for: Date()))")
That outputs:
Start of day in UTC is 2021-05-27 00:00:00 +0000
Start of day in local time zone is 2021-05-26 04:00:00 +0000
That's because right now, which is 20:56 on 26 May in my time zone, it's 0:56 on 27 May in UTC. So if I ask the UTC calendar for the start of day for now (Date()) I get midnight on 27 May, in UTC.
If I ask the same question of my local calendar, I get midnight on 26 may in my time zone, which is 4:00 AM on 26 May in UTC.
If I ran the same code this morning at 8:00 AM in my time zone, I would have gotten the output:
Start of day in UTC is 2021-05-26 00:00:00 +0000
Start of day in local time zone is 2021-05-26 04:00:00 +0000
(Since at 8:00 AM on 26 May in EDT is also 26 May in UTC.)
It's tricky and not 100% reliable and only works if you know that all days were created using startOfDay. But first you need to decide what you want. Say one date was created at 10pm in the New York, and one at exactly the same moment in London, at 4am the next day. What day do you want to be stored?
If your date stored is 25th, 10pm, then you know it was created in a timezone where the day started at 10pm UTC. You are lucky, there are only two time zones that would have created this, one without DST, one with DST. So you know it happened in one of these two time zones, within 24 hours.
Unfortunately, time zones cover 26 hours. Fortunately, only some islands in the Pacific Ocean have same time and different dates (+13 and -11 hours). For these places, you cannot possibly know which date is correct, but very few people would be affected.

dayjs - how to create an ISO datetime string in a different timezone?

I am building an browser-based application where the user sets the timezone of their application, e.g. "America/New_York". I have a part of the application that allows users to set reminders and I want the user to specify that they want, for example, to set a reminder for 28th Jan 2020 at 9am in their timezone. This should work such that it they are on holiday in London and used the application to set this reminder, displaying this reminder would still always be in the New York timezone. I store the dates as UTC in the applications database and when converting this back show the user will display it according to their timezone.
I have tried this method in Codesandbox, to convert the date to UTC to store in the database:
const dateInNewYork = dayjs("2020-01-28 09:00:00", { timeZone: "America/New_York" }).toISOString();
// displays as 2020-03-29T11:00:00.000Z - shouldn't this be 2020-01-28T14:00:00.000Z ?
What am I doing wrong here?
let timeSt = dayjs(time).unix()* 1000;
timeSt += 60*60*1000*8 //8 is means china beijing time.
let whatYouNeed = dayjs(timeSt).format("YYYY-MM-DD HH:mm");

ember-cli and Rails 5 api date handling

I am trying out rails 5 api and ember-cli (2.11) for the first time. I am having trouble with date handling.
I have a date attribute in rails outputting json like
"2017-03-15"
The date (in ember inspector) becomes
Tue Mar 14 2017 20:00:00 GMT-0400 (EDT)
I use a seed file to create records like:
Planting.create(planting_type: 'seed', planting_date_begin: Date.new(2017,8,1))
I only care about date (not time). How do I get date to display correctly in Ember as well as determine if other dates are within date range (date math)?
Do I need to change my rails attribute to DateTime? If I do change to DateTime will Ember still need adjustment for timezone? What about my seed file...will I need save like a timestamp with no timezone but with time info?
Ember was converting my date into a time with wrong time zone. using the add-on https://github.com/thoughtbot/ember-utc-transform changes zone to utc resolved my issue

Format date time in gwt with timezone

I am need to format a date and display it to users based on users location.
I am trying to format the time using the following code
DateTimeFormat.getFormat("h:mm a z").format(new Date(timeInMillis))
This is the result i am getting "5:18 PM UTC-4" for new york users and "2:18 PM UTC-7" for seattle users. How do i generate string like "5:18 PM EST" for new york users and "2:18 PM PDT" for seattle users?
Note: the problem with using format(new Date(time), timezone) is that how to create a timezone object based on user locale? Timezone.createTimeZone(int) gives SimpleTimeZone implementation which will produce "UTC-4", in-order to generate "PDT", timezone has to be created with Timezone.createTimeZone(timezoneJson: string) but issue in this is that we have to pick the timezone at the compile time to create the input timezone json string.
Thanks in advance
You need to pass a TimeZone object to the formatter:
format.format(new Date(), timeZone));
Note that the best way to create TimeZone is from a JSON string that contains information on changes to time zone in the past. If you app does not deal with time in the past, then this may not be necessary.

Mongodb date is off by 1 hour

I am running mongodb on ubuntu server. The server time is
root# date
Thu Sep 13 21:15:58 BST 2012
But when I run the following command I get a different result
root# mongo
MongoDB shell version: 2.2.0
connecting to: test
> new Date()
ISODate("2012-09-13T20:15:58.670Z")
There is exactly one hour difference. When I update a documents updated_on field with php using MongoDate(), the value of the field is still 1 hour off.
[EDIT]
Actually I just checked my php error log and the time in the log file is 1 hour off as well
[13-Sep-2012 20:11:14 UTC] Log Message (Time should be 21:11:14)
Mongo tells you
2012-09-13T20:15:58.670Z
Z = Zulu time / Zero offset / UTC. You can also express the time in that TZ as 2012-09-13T20:15:58.670+00:00, as defined in the ISO8601 standard by the way.
BST is UTC+1. So, they are the same time but in different time zones.
You can resolve this issue by displaying the DateTime with ToLocalTime method.
MVC C# Example: #Model.StartDate.ToLocalTime()
This is due to the way MongoDB store datetime in BST format. So the daylight savings time or the time zone of the server will have an effect on the actual date time returned to the application. This simple code will be able to format as usual with ToString("dd MMMM yyyy hh:mm tt") or any other format based on your requirements.
Here you need to understand a concept in time setting in clocks called daylight saving time. In some countries around the world the clock is advanced by 1 or more hours to experience day light by one more hour. The difference between IST and GST is 5.30 hrs but the actual time difference is between New Delhi and London time is 6.30 hrs. See this article from 4GuysFromRolla for setting and using server time.
On windows change your timezone.
Controll Panel -> Date and Time -> Change on timezone -> (UTC) Coordinated universal time.
And then just change your time