NSCalendarIdentifierRepublicOfChina vs NSCalendarIdentifierChinese? - ios

I wonder what is the different of NSCalendarIdentifierRepublicOfChina (NSRepublicOfChinaCalendar) and NSCalendarIdentifierChinese (NSChineseCalendar) but can't find any information from Apple Developer website.
Can anyone help me?
Thanks

From NSLocale Calendar Keys:
NSRepublicOfChinaCalendar
Identifier for the Republic of China
(Taiwan) calendar.
A Chinese calendar can be created, and you can do calendrical
calculations with it, but you should not use it for formatting as the
necessary underlying functionality is not working correctly yet.
Available in OS X v10.6 and later.
Deprecated in OS X v10.10.
and
NSChineseCalendar
Identifier for the Chinese calendar.
Available in OS X v10.4 and later.
Deprecated in OS X v10.10.
So
NSRepublicOfChinaCalendar (which has been deprecated in favor of
NSCalendarIdentifierRepublicOfChina) is for the calendar used in Taiwan.
As I understand it, this is the Minguo calendar and differs from the Gregorian calendar
by a difference of 1911 in the years.
NSChineseCalendar (which has been deprecated in favor of NSCalendarIdentifierChinese) is for the traditional Chinese calendar.
The following code prints the current date (January 10, 2015 in the Gregorian calendar)
in both those calendars:
let fmt = NSDateFormatter()
fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX")
fmt.dateStyle = .FullStyle
let rocCal = NSCalendar(calendarIdentifier: NSCalendarIdentifierRepublicOfChina)
fmt.calendar = rocCal
println(fmt.stringFromDate(NSDate()))
// Saturday, January 10, 104 Minguo
let chineseCal = NSCalendar(calendarIdentifier: NSCalendarIdentifierChinese)
fmt.calendar = chineseCal
println(fmt.stringFromDate(NSDate()))
// Saturday, Month11 20, 2014(jia-wu)
The latter is the 20th day in the 11th month in the year of the horse (Jia Wu)

Related

Transform Epoch UTC to String EST using momentjs

I have two input variables: an epoch time in UTC time zone and the name of the actual time zone. How do I get a formatted day/time using moment.js that would take in account the DST changes. I tried this code but it doesn't do the trick. What am I doing wrong, please?
var abs_time = 1611188219.277; // this is UTC coresponding to 1/21/2021 18:31:37 UTC
var timezone = "America/New_York"; // this the actual time zone
var mom = moment(abs_time * 1000).format();
var date_time = moment.tz(mom, timezone).format('ddd, MMM DD YYYY - HH:mm');
console.log(date_time);
//actual result: Thu, Jan 21 2021 - 18:31
//desired result: Thu, Jan 21 2021 - 13:31 - in the summer this should only be 4 hour difference
First, 1611188219.277 actually corresponds to 2021-01-21T00:16:59.277Z, not the time you gave in your question (assuming it is a Unix timestamp with seconds precision). This can be seen with the following code:
const d = new Date(1611188219.277 * 1000);
const s = d.toISOString();
console.log(s);
You can get the equivalent local time in a specific time zone without any libraries, as long as you're satisfied with the output produced by the toLocaleString function.
const d = new Date(1611188219.277 * 1000);
const s = d.toLocaleString(undefined, { timeZone: 'America/New_York' });
console.log(s);
Note that undefined in the above code will use the browser's current language. If you want a specific language, you could pass its language code there instead (such as en or en-US, etc.)
In general, due to its project status, you should avoid using Moment unless it's already being used in an existing project. If however, you must use Moment and Moment-TimeZone for this, you can do the following to get the same result:
const m = moment.tz(1611188219.277 * 1000, 'America/New_York');
const s = m.format('ddd, MMM DD YYYY - HH:mm');
console.log(s);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.32/moment-timezone-with-data-10-year-range.min.js"></script>
I used the same format from your question, but of course you could change this as desired.
You might also consider using Luxon (the successor to Moment), or Date-fns, or several other libraries.
And yes, all of the above will correctly take daylight saving time into account.

iOS 12 stringFromDate method returns incorrect value

In iOS 12, I have noticed that the [NSDateFormatter stringFromDate] method returns an incorrect value on a simulator iPad, but the correct value on a physical iPad.
Example code:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"c"];
NSDate *currentDate = [NSDate date];
// Returns correct value on both physical and simulator iPads (eg. Fri Oct 19 15:39:53 2018)
NSString *currentDateAsString = [dateFormat stringFromDate:currentDate];
// Physical iPad: 5 (correct)
// Simulator iPad: 6 (incorrect)
Both iPads have the same date/time settings (eg. same timezone). What is the cause of this bug?
Check the first weekday on your real and simulator iPads to see if they match:
NSCalendar.current.firstWeekday
and take that value into your calculations on the weekday taken from the date formatter.
The first day of week on iOS depends on the Region settings. Double check the settings in Settings -> General -> Language & Region -> Region on both your real and simulator iPads. Also, it may worth to check the first day of week on your Mac in System Preferences -> Language & Region -> First day of week too.

NSDateFormatter fails to return a datetime for UK region with 12 hour clock set [duplicate]

This question already has answers here:
What is the best way to deal with the NSDateFormatter locale "feature"?
(4 answers)
Closed 7 years ago.
This code works for every region/locale combination I can determine EXCEPT if I set my phone to UK region with the 12 hour clock set. Can anyone tell me why?
This works for every region including the UK with 12 hour clock set:
NSDateFormatter *theDateFormatter = [[NSDateFormatter alloc] init];
theDateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ";
NSString *theLastFetchDateString = #"2015-11-13T01:47:52.4630000Z";
NSDate *theLastFetchDate = [theDateFormatter dateFromString:theLastFetchDateString];
This works in every region EXCEPT the UK with the 12 hour clock set:
NSDateFormatter *theDateFormatter = [[NSDateFormatter alloc] init];
theDateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ";
NSString *theLastFetchDateString = #"2015-11-13T18:14:44.1230000Z";
NSDate *theLastFetchDate = [theDateFormatter dateFromString:theLastFetchDateString];
In the second case, theLastFetchDate is always nil.
The main difference I see is the second date is stored in 24 hour format where the parsing device is in 12 hour format, but the formatter HH should be able to handle that, yeah?
The other weird thing, and it is probably just a display thing, is the UK 12 hour clock formats times with 'a.m.' or 'p.m.' where the US 12 hour clock formats them as 'AM' or 'PM'.
You are parsing a RFC 3339/ISO 8601 date. As such, you should set the locale of the formatter to be en_US_POSIX.
theDateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
See Apple Technical Q&A 1480.

Getting current time of day down to milliseconds error

I have been attempting to access the time of day in hour:minute:second format however all that these
println(CFTimeZoneCopySystem())
println(CFTimeZoneCopyDefault())
println(gettimeofday)
println(CACurrentMediaTime)
print are
America/New_York (EDT) offset -14400 (Daylight)
America/New_York (EDT) offset -14400 (Daylight)
(Function)
(Function)
I don't understand why these are simply printing out "(function)" and I am also unsure as to what time format 14400 is. I want to be able to access something that would be accurate across bluetooth devices. so that is why I would prefer to access milliseconds. I know there was another question similar to this one however I do not think they received this article as well as I do not understand objective-C
You can use the code below:
let formatter = NSDateFormatter()
//formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) // you can set GMT time
formatter.timeZone = NSTimeZone.localTimeZone() // or as local time
formatter.dateFormat = "HH:mm:ss.SSS"
println(formatter.stringFromDate(NSDate()))
Output: "05:57:26.123"

Unix time with NSDate reveals erroneous results

I live in Denmark (UTC + 1 ) and I am working with a webapi that sends my app a unix timestamp since 1970-1-1 00:00:00. The time is in the future (train depatures)
If I check the timestamp in Numbers or Excel it gives me the correct time
To calculate the number of minutes until the train departures I do like this:
let unixTimeTrainDeparture = 1419327780 //(or some time in the future)
let unixRightNow = NSDate().timeIntervalSince1970
let minutesToDeparture = (Int(unixTimeTrainDeparture) - Int(unixRightNow))/60
However this gives 60 minutes too much?
And If I do a
let dateTest = NSDate(string: "1970-01-01 00:00:00 +0000")!
will give me 1 jan 1970 :01:00:00 +0000
This does not make sense to me. It is like the timeIntervalSince1970 gives me 3600 sec too less, as it starts from 1970-1-1 01:00 rather than 00:00? It this a bug or is it the way it should be?
I can correct the time by using the
let tz = NSTimeZone.defaultTimeZone()
let seconds = tz.secondsFromGMTForDate(NSDate())
and then subtracting the seconds from my result. However, what happens when we move into summer time?
timeIntervalSince1970 always gives the time in GMT. Your unixTimeTrainDeparture is probably the time in GMT+1, which explains the 60 minute difference (or 120 minutes in summer time). Same goes with the string conversion - you input a GMT time and it outputs the date in whatever timezone you have configured (I'm guessing your computer's setting is GMT+1 as well).
When working with timezones, always start with GMT/UTC and don't do any timezone conversions until displaying the date to the user.
Do you have any control over the web API? If so - configure it to send GMT instead. This should completely avoid time zone and daylight savings issues.
If you cannot do that you will have to implement some function to convert the timestamp yourself, accounting for the possibility that a future timestamp could be in a different timezone (eg daylight savings). NSTimeZone might be very useful for this!
Hope I have understood your problem correctly!
Edit, added example that should handle DST:
// Date far in the future in DST, replace this
let unixTimeTrainDeparture = NSDate(timeIntervalSince1970: 1436447418)
let now = NSDate()
// Assume unixTimeTrainDeparture is in the Copenhagen timezone
let tz = NSTimeZone(name: "Europe/Copenhagen")
// This is 3600 in non-DST, otherwise 7200
let offset = tz!.secondsFromGMTForDate(unixTimeTrainDeparture)
let realUnixTimeTrainDeparture = Int(unixTimeTrainDeparture.timeIntervalSince1970) - offset
let timeToDeparture = realUnixTimeTrainDeparture - Int(now.timeIntervalSince1970)

Resources