How do you return the system time zone as a string? - objective-c

I have an app where I set time zones for various cities around the globe. I have no problem doing this and it works great. When the app first loads, it finds your current location (lat & long) and sets the time zone using the device default time zone. I need to return the default time zone in a string, so I can display it. I don't want "GMT" or "EDT", I would like it in the format of "America/New_York" or 'Europe/London". Any ideas?

It sounds like you want this:
NSString *timeZoneName = [[NSTimeZone localTimeZone] name];
That returns "America/New_York" for me, here in the EST time zone.
Or given any NSTimeZone *tz you can get its [tz name], which is the conventional name you are looking for (e.g. "Asia/Tokyo" or "Europe/London".
Look at +[NSTimeZone knownTimeZoneName] for a list of possible names.
I hope that helps.

I don't think there is an object that automatically correlates the time zone to a physical place.
I see you've tagged this objective-c, but in C# you could do something simple like this:
public Enum TimeZone
{
[Description("New York")]
EDT,
[Description("Los Angeles")]
PST
}
public static string GetDescription(Enum value)
{
FieldInfo fi= value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return (attributes.Length>0)?attributes[0].Description:value.ToString();
}
i'm not sure how easily portable this is to objective-c, and it does require using the reflection library in C#.

Well, you're making the assumption that EDT is the same time zone as America/New_York. It isn't. :) Yes, they're the same UTC offset, but as far as your system is concerned, they are defined independently. There's no strong association between them that Cocoa knows about.
As well, if the user gives you EDT, do you return New_York? Toronto? Panama? There's not a 1:1 correspondence. Oh, and: EDT isn't even unique to a single UTC offset. Australian Eastern Daylight Time is also abbreviated EDT, I'm told by the Cocoa docs.
There is a [NSTimeZone abbreviationDictionary] map between abbreviations and long names, but again, they're arbitrarily chosen when there's more than one association (such as New York and Panama.)
What is it you're trying to accomplish in a broader sense? What's your goal? Tell us and we may be able to suggest an alternate way to achieve it. :)

Related

VB.Net Convert time from UTC to Local

I am working on a news website and I am saving all dates in the database in UTC. Then, depending on the browser/machine location, I want to display the date/time correspondingly (Convert from UTC to the Local time of the machine/browser).
First of all, I would like to know if I am doing this the way it should be done or not (UTC dates in the database).
Second, I wonder why isn't it that straightforward to do so in VB.NET? Below are the approaches I tried but none worked as needed:
Approach 1:
TimeZoneInfo.ConvertTimeFromUtC
This kept returning the server time and not the client/machine time.
Approach 2:
Dim TimeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Middle East Standard Time")
Dim Dated As DateTime = TimeZoneInfo.ConvertTimeFromUtC(TempDate, TimeZone)
This worked but not as intended. This converted the UTC date/time in the database to the Middle East Time Zone but any user from any other place in the world will only see the date/time in Middle East Time Zone and not in the actual timezone of his place. Also, I am not sure if the conversion considers DayLightSaving or not.
Approach 3:
I tried to fix this using JavaScript. I created a cookie that saves the offset from UTC and tried handling the offset in VB.NET and do the conversion.
<script>
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getTimeOffset() {
var offset = new Date().getTimezoneOffset();
setCookie("_tz", offset);
}
</script>
JavaScripts returns the correct Offset and I am saving this offset in a cookie. Since JavaScript launches after Page_Load, I am calling the JavaScript function getTimeOffset() on Page_Init:
ScriptManager.RegisterStartupScript(Me, Page.GetType, "Script", "getTimeOffset();", True)
The cookie is being created before the page is rendered and the offset stored in the cookie is correct (This is what I actually want!). The problem here is on the first load. VB.NET reads the cookie value as empty string on the first load. On the second Page_Load onwards, VB.NET reads the cookie value and does the conversion correctly.
Approach 4
Tried to get the offset using all the examples in this fiddle but the offset is always 0 which is wrong.
Summary
I wonder if there is any function I missed in VB.NET to avoid all that hassle. Shouldn't it be an easy task to convert date/time from UTC to Local?
Please let me know if there is anything I am doing wrong or if there is a better alternative.
Your back-end code doesn't know anything about the time zone of the browser. It doesn't matter what language you are using, only the browser will know anything about the user's time zone.
When .Net code (regardless of VB or C#) refers to "local", it means the local time zone of where that code is running. In other words, in an ASP.Net web application, that's the local time zone of your server, not of the user. Generally speaking, the server's local time zone is usually irrelevant.
To achieve your goal, break the problem up into two parts.
Get the user's time zone in the browser, send it to the server.
Convert time on the server, using the time zone passed in.
For step 1, read this answer I posted to a different question. Note that the output will be an IANA time zone identifier. Do not pass a numeric offset, as it does not carry enough information to properly convert different points in time (consider daylight saving time, and other anomalies with time zones).
For step 2, you'll need to choose between one of these approaches:
You can use the IANA time zone identifier natively with TimeZoneInfo if you're running .NET Core on a non-Windows OS, or with the Noda Time library on any platform.
You can convert the IANA time zone identifier to a Windows time zone identifier using my TimeZoneConverter library, and then you can use the result with the TimeZoneInfo class on Windows.
One little thing: You used TimeZoneInfo.ConvertTimeToUtc, where I think you meant TimeZoneInfo.ConvertTimeFromUtc. Be careful of the directionality of the conversions.
I'll also point out that there's an alternative approach, which is to pass the UTC timestamp all the way down to the browser, and just convert from UTC to local time in JavaScript. Then you don't need to do any time zone detection at all.

Objective-C format date and string

guys
I have two question to ask, they're easy, but bothering me for a while.
I access my .NET test WebService, and it return two parameters to me.
One is a date data just like "/Date(1332399761677+0800)/", and I dont know
how to format it to the normal date format.
Two is a NSString data looks like "12000.00000",and I want to change it to
the format like this:"12000.00".
So,please help me with this two problems. Thank you in advance.
1332399761677 looks like a Unix date, so if you grab that part of the string, use NSString doubleValue to turn it into a double, then use NSDate dateWithTimeIntervalSince1970:, you should be able to get a date. +0800 looks like a timezone, but you wouldn't need the timezone to get the date given a Unix date: 1332399761677 would specify a specific point in time, irrespective of timezones.
As for "12000.00000", you would use doubleValue to make it into a double, make an NSNumberFormatter with its maximumFractionDigits and minimumFractionDigits set to 2, then use stringFromNumber:.

CFAbsoluteTimeGetCurrent and DST

I'm developing an app for iPhone that uploads pictures to a webserver. These pictures have the time of when they were taken in the filename. Since they can be taken from anywhere in the World, I have to keep attention to timezones and DST. I thought I can use CFAbsoluteTimeGetCurrent, that shouldn't be localized ([NSDate date] returns the localized version of time, with or without "AM", "PM", "p.m." or any other variant... for example it returns Arabian characters, if your phone is set in arabic language!).
So, can you suggest me a function to convert CFAbsoluteTimeGetCurrent to a "MySQL like" date, something like "2011-11-03 14:12:10"?
My second question is: what about timezones and daylight saving? CFAbsoluteTimeGetCurrent always returns an UTC date, no matter how the iPhone timezone is set? Is it always DST-free?
Of course I know that the local iPhone date/time could be wrong, but milliseconds-precision is not important for my application :)
Thank you in advance!
What on earth do you mean by
([NSDate date] returns the localized version of time, with or without "AM", "PM", "p.m." or any other variant... for example it returns Arabian characters, if your phone is set in arabic language!).
[NSDate date] returns an NSDate* object. I'm assuming what you really mean is the output of -[NSDate description] returns a string localized in the user's current locale, but then the question is, why are you depending on the output of -[NSDate date]? If you need to format a date a certain way, you should use an NSDateFormatter.
CFAbsoluteTime represents a moment in time, independent of time zones or localization settings. If you want to format a date (i.e. an NSDate object) you should look at NSDateFormatter, which lets you specify the exact format and localization (if any) of the output string. (If you need to work at the Core Foundation level, CFDateFormatter does the same thing.)

Parsing Datetime

I have a date time as a string, eg. "2010-08-02", I'm trying to convert it to UTC with the following code snippet
DateTime.ParseExact("2010-08-02Z", "yyyy-MM-ddZ", CultureInfo.InvariantCulture)
When I print to the console, I get the following: 8/1/2010 5:00:00 PM.
Is there a reason why the date shows up as the date before the date I'm trying to parse? I could just add a day to this to advance to the original day, but I wanted to see if there's anything I'm doing wrong in the formatting that's causing this.
EDIT: I had a mixture of being correct and not :)
It's showing you the local time represented by the UTC string. It's annoying that DateTime doesn't make this sort of thing clear, IMO. Additionally, I don't think you want to use 'Z' as the format specifier for the time zone; that's not actually a valid format specifier; it should be 'z', - but that's meant for things like "+01:00". I think you should be using 'K'. Frankly it's not clear, but if you use 'K' it round-trips correctly, certainly ('Z' roundtrips too, but only because it ignores it, treating it as plain text).
You can fix it by just calling ToUniversalTime, or (preferred IMO) specifying DateTimeStyles.AdjustToUniversal as an extra argument:
DateTime dt = DateTime.ParseExact("2010-08-02Z", "yyyy-MM-ddK",
CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal);
The UTC of midnight for 2010-08-02 happens to be at 5pm on 2010-08-01.
If the original string is just a date in the format "2010-08-02" (without the Z), then why not just:
DateTime.SpecifyKind(
DateTime.ParseExact("2010-08-02",
"yyyy-MM-dd",
CultureInfo.InvariantCulture),
DateTimeKind.Utc);
ParseExact will presumably return a DateTime with Kind = Unspecified, and you can make it UTC or Local as you wish using SpecifyKind.

Change UIDatePicker from 12 hour clock to 24 hour clock and back

I'm sorry to make my first question here a bit of a simple one -- I've spent a day reading the NSLocale and NSCalendar class descriptions but I couldn't see if this was possible.
I have a UIDatePicker in the UIDatePickerModeDateAndTime mode. It is currently displaying date and time according to the user's locale, which is the default behavior.
I would like to be able to offer the option to show the UIDatePicker in either 12-hour or 24-hour time format. Detecting which time format the user is currently using isn't a problem, but I'm not clear on how to change just the time format of UIDatePicker without entirely throwing out the user's locale settings (since the picker also displays the localized days of the week and months). UIDatePicker supports setting its locale and setting its calendar.
So, question one is whether this is something I should be trying to do via NSLocale or NSCalendar, and question two is if anyone can recommend a way to isolate the time format without throwing out the rest of the user's locale settings.
Thanks for any suggestions.
This is not the answer you are looking for, but in Cocoa you could create an NSDateFormatter and attach it to an NSDatePicker (which is an NSControl) using setFormatter. Unfortunately the equivalent iPhone class (UIControl) does not support this yet. I raised a bug with Apple about it and this is a known issue, although they wouldn't tell me if/when they plan to fix/enhance it.
OK, after reading the last two years' worth of others asking the same question here, it seems that there is no way to do this since the UIDatePicker uses the user's country setting instead of the user's locale setting, and that can't be overridden programmatically. I filed a bug.
I have solved this problem by using the user input of AM/PM by initializing another variable as a string of either AM or PM based upon the 12 hour format. The new hour in 24 hour format is put into NSCalendar. To wit:
var hra = 1//ENTER INITIAL HOUR (HH)
var dna = "PM"//ENTER "AM" OR "PM"
if hra <= 12 && dna == "PM"{
hra = hra + 12
}
The variable hra now takes the value of the 24 hour format.