Are there time zone abbreviations for UTC-12 and UTC+12? - ios
I'm working on a problem where I want to do calculations on NSDates where a single NSDate gives different dd/mm/yyyy values in different time zones.
To do that I'm currently using New York City (EST) and Aukland, NZ, since they are frequently on different dates.
I'd like to be able to use the time zones on either side of the international date line, UTC+12, and UTC-12. There appears to be a standard abbreviation for UTC+12, ANAT, for Anadyr, Russia. However, the iOS implementation of TimeZone/NSTimeZone doesn't seem to recognize it. There also does not seem to be an abbreviation for UTC-12 (which would be in Alaska).
Does anybody know if there are such abbreviations for UTC+12 and UTC-12 that iOS (or Mac OS, for that matter) recognizes?
It looks like the answer is no.
I wrote some code to fetch all the system time zones, sort them by offset, and print them:
typealias timeZoneTuple = (abbreviation: String, name: String, offset: Int)
let timeZones = TimeZone.abbreviationDictionary
let mappedTimeZones: [timeZoneTuple] = timeZones
.map {key, value in
var offset = 0
if let timeZone = TimeZone(abbreviation: key) {
offset = timeZone.secondsFromGMT() / 3600
}
return (abbreviation: key, name: value, offset:offset)}
.sorted {$0.offset < $1.offset}
mappedTimeZones.forEach {
let abbreviation = $0.abbreviation.padding(toLength: 4, withPad: " ", startingAt: 0)
let name = $0.name.padding(toLength: 20, withPad: " ", startingAt: 0)
print("abbreviation = \(abbreviation), offset = \(name), val = \($0.offset)")}
The output of the above code is:
abbreviation = HST , offset = Pacific/Honolulu , val = -10
abbreviation = AKDT, offset = America/Juneau , val = -9
abbreviation = AKST, offset = America/Juneau , val = -9
abbreviation = PST , offset = America/Los_Angeles , val = -8
abbreviation = PDT , offset = America/Los_Angeles , val = -8
abbreviation = MDT , offset = America/Denver , val = -7
abbreviation = MST , offset = America/Denver , val = -7
abbreviation = CDT , offset = America/Chicago , val = -6
abbreviation = CST , offset = America/Chicago , val = -6
abbreviation = EDT , offset = America/New_York , val = -5
abbreviation = PET , offset = America/Lima , val = -5
abbreviation = EST , offset = America/New_York , val = -5
abbreviation = COT , offset = America/Bogota , val = -5
abbreviation = ADT , offset = America/Halifax , val = -4
abbreviation = AST , offset = America/Halifax , val = -4
abbreviation = CLT , offset = America/Santiago , val = -3
abbreviation = CLST, offset = America/Santiago , val = -3
abbreviation = ART , offset = America/Argentina/Bu, val = -3
abbreviation = BRST, offset = America/Sao_Paulo , val = -2
abbreviation = BRT , offset = America/Sao_Paulo , val = -2
abbreviation = GMT , offset = GMT , val = 0
abbreviation = WET , offset = Europe/Lisbon , val = 0
abbreviation = BST , offset = Europe/London , val = 0
abbreviation = WEST, offset = Europe/Lisbon , val = 0
abbreviation = UTC , offset = UTC , val = 0
abbreviation = CEST, offset = Europe/Paris , val = 1
abbreviation = WAT , offset = Africa/Lagos , val = 1
abbreviation = CET , offset = Europe/Paris , val = 1
abbreviation = CAT , offset = Africa/Harare , val = 2
abbreviation = MSD , offset = Europe/Moscow , val = 3
abbreviation = EAT , offset = Africa/Addis_Ababa , val = 3
abbreviation = IRST, offset = Asia/Tehran , val = 3
abbreviation = MSK , offset = Europe/Moscow , val = 3
abbreviation = EET , offset = Europe/Istanbul , val = 3
abbreviation = EEST, offset = Europe/Istanbul , val = 3
abbreviation = GST , offset = Asia/Dubai , val = 4
abbreviation = IST , offset = Asia/Calcutta , val = 5
abbreviation = PKT , offset = Asia/Karachi , val = 5
abbreviation = BDT , offset = Asia/Dhaka , val = 6
abbreviation = WIT , offset = Asia/Jakarta , val = 7
abbreviation = ICT , offset = Asia/Bangkok , val = 7
abbreviation = SGT , offset = Asia/Singapore , val = 8
abbreviation = HKT , offset = Asia/Hong_Kong , val = 8
abbreviation = PHT , offset = Asia/Manila , val = 8
abbreviation = KST , offset = Asia/Seoul , val = 9
abbreviation = JST , offset = Asia/Tokyo , val = 9
abbreviation = NZDT, offset = Pacific/Auckland , val = 13
abbreviation = NZST, offset = Pacific/Auckland , val = 13
So it looks like UTC-12, UTC-11, UTC-1, UTC+10, UTC+11, and UTC+12 are all missing from the "named" timezones that are available in Cocoa.
EDIT:
Based on a comment from #MattJohnson, it seems that the identifiers is a better way to get the list of available time zones. Modifying my code to use identifiers instead:
struct timeZoneStruct: CustomStringConvertible {
let identifier: String
var offset: Int
var description: String {
let displayOffset = String(format: "%3d", offset)
let displayIdentifier = (identifier + ",").padding(toLength: 30, withPad: " ", startingAt: 0)
return "identifier = \(displayIdentifier) offset = \(displayOffset)"
}
}
let timeZoneIDs = TimeZone.knownTimeZoneIdentifiers
let mappedTimeZones: [timeZoneStruct] = timeZoneIDs
.map {identifier in
var offset = 0
if let timeZone = TimeZone(identifier: identifier) {
offset = timeZone.secondsFromGMT() / 3600
}
return timeZoneStruct(identifier: identifier, offset: offset)}
.sorted {$0.offset < $1.offset}
mappedTimeZones.forEach {
print($0.description)
}
That yields a list of time zones ranging from UTC-11 (Pacific/Pago_pago) to UTC+14 (Pacific/Apia)
(There are quite a few duplicates for most time zones, so the list is too long to include here.)
So it seems there are defined time zones for offsets from UTC-11 to UTC+14. There is not a time zone for UTC-12 however, even though Baker Island, at Lat/Long: 0°12'N / 176°29'W, is in UTC-12. Curious.
This is the simplest way to get all timezones with their respective abbreviation.
P.S Not all timezones have their proper 3-Letter Abbreviations.
let timezoneList = NSTimeZone.knownTimeZoneNames
for i in 0...timezoneList.count - 1 {
let locale = NSTimeZone.init(name: timezoneList[i])
print("Region: \((locale?.name)!) Abbr: \((locale?.abbreviation)!)")
}
Also total 51, 3-lettered Abbreviations are present:
print(TimeZone.abbreviationDictionary.count)
You can also explore https://developer.apple.com/documentation/foundation/timezone for more.
Related
Set tickInterval in format HH:mm am/pm of a HIChart's Line chart using Swift 5.0
I want to set intervals as per the below image. I have tried to set using it below code. let xAxis = HIXAxis() xAxis.type = "datetime" xAxis.dateTimeLabelFormats = HIDateTimeLabelFormats() xAxis.dateTimeLabelFormats.day = HIDay() xAxis.dateTimeLabelFormats.day.main = "%l:%M" xAxis.min = NSNumber(value: ConverteddateFrom ) //Millisecond 12 AM midnight from starting of the day xAxis.max = NSNumber(value: ConverteddateEnd) //Millisecond 12 AM to end of the day xAxis.tickInterval = NSNumber(value: 4 * 3600 * 1000 ) xAxis.categories = DateList options.xAxis = [xAxis] let plotoptions = HIPlotOptions() plotoptions.series = HISeries() plotoptions.series.label = HILabel() plotoptions.series.label.connectorAllowed = NSNumber(value: false) // plotoptions.series.pointStart = 12 // plotoptions.series.pointInterval = NSNumber(value: 4) // plotoptions.series.pointIntervalUnit = "AM" options.plotOptions = plotoptions let line1 = HILine() line1.name = "Phase B" line1.data = PhaseBList let line2 = HILine() line2.name = "Phase R" line2.data = PhaseRList let line3 = HILine() line3.name = "Phase Y" line3.data = PhaseYList options.series = [line1, line2, line3] options.responsive = responsive options.colors = ["#7CB5EC","#F94F6C", "#FFB647"] inputVoltage.options = options but I didn't get proper x-axis with intervals. can anybody help me on this? I am getting on x-axis points something like starting point as 20:00 to 16:00 with interval of 4 hours. I am expecting it from 12Am to 12Am. Also I can't see the data on graph.
You have 4 hour tick interval, so probably you need to change dateTimeLabelFormats from day to hour: xAxis.dateTimeLabelFormats = HIDateTimeLabelFormats() xAxis.dateTimeLabelFormats.hour = HIHour() xAxis.dateTimeLabelFormats.hour.main = "%l %P" xAxis.dateTimeLabelFormats.day = HIDay() xAxis.dateTimeLabelFormats.day.main = "%l %P" API Reference: https://api.highcharts.com/ios/highcharts/
I have got the solution - 1 - The problem was with the data presenting. Initially I was added the data array only whereas we have to add data along with its correspondence date. So it becomes array of array like this - line1.data = [ [1562106600000, 0], [1562121000000, 0.25] ] 2 - x axis time from 20:00 to 16:00 is because of UTC time. Solution is : options.time = HITime() options.time.useUTC = false //options.time.timezone = "Asia/Kolkata" // If you want to set timezon you can 3 - converting the date into AM/PM in 12 hrs format. xAxis.type = "datetime" xAxis.dateTimeLabelFormats = HIDateTimeLabelFormats() xAxis.dateTimeLabelFormats.hour = HIHour() xAxis.dateTimeLabelFormats.hour.main = "%l %P" xAxis.dateTimeLabelFormats.day = HIDay() xAxis.dateTimeLabelFormats.day.main = "%l %P" xAxis.min = NSNumber(value: ConverteddateFrom ) //Millisecond 12 AM midnight from starting of the day xAxis.max = NSNumber(value: ConverteddateEnd) //Millisecond 12 AM midnight from ending of the day xAxis.tickInterval = NSNumber(value: 4 * 3600 * 1000 ) options.xAxis = [xAxis] This is how my graph is looking now -
Get date value from dictionary
I have a dictionary declared like this: var result:[Workout] = [] The value in result is following, using print(result): [Workout { date = 2019-03-06 22:18:41 +0000; name = Legday; exercise = Bbb; sets = 2; reps = 1; kg = 77; notes = Bb; }, Workout { date = 2019-02-24 18:41:07 +0000; name = bvcj; exercise = Barbell Bench Press; sets = 1; reps = 1; kg = 87; notes = Kjj; }, Workout { date = 2019-02-22 08:02:23 +0000; name = Chest; exercise = Barbell Bench Press; sets = 3; reps = 6; kg = 95; notes = Ok med spot; }, Workout { date = 2019-02-22 08:02:23 +0000; name = Chest; exercise = Dips; sets = 2; reps = 6; kg = 40; notes = Lett, 1 ektra rep på siste sett; }, Workout { date = 2019-02-22 08:02:23 +0000; name = Chest; exercise = Incline Barbell Bench Press; sets = 2; reps = 6; kg = 72.5; notes = Tungt; }, Workout { date = 2019-02-22 08:02:23 +0000; name = Chest; exercise = Triceps Pushdown; sets = 3; reps = 12; kg = 14.5; notes = Ok; }, Workout { date = 2019-02-19 13:38:35 +0000; name = Legday; exercise = Squat; sets = 2; reps = 2; kg = 77.5; notes = Lett; }, Workout { date = 2019-02-19 13:38:35 +0000; name = Legday; exercise = Leg Press; sets = 9; reps = 8; kg = 100; notes = Tungt; }, Workout { date = 2019-02-18 10:54:34 +0000; name = Legday; exercise = Barbell Squat; sets = 3; reps = 6; kg = 75; notes = Tungt; }, Workout { date = 2019-02-18 10:54:34 +0000; name = Legday; exercise = Leg Extension; sets = 10; reps = 10; kg = 32; notes = Lett; }, Workout { date = 2019-02-17 21:48:52 +0000; name = Legday; exercise = Squat; sets = 3; reps = 6; kg = 60; notes = Lett; }, Workout { date = 2019-02-17 21:48:52 +0000; name = Legday; exercise = Tåhev; sets = 4; reps = 12; kg = 40; notes = Tungt; }, Workout { date = 2019-02-17 21:48:52 +0000; name = Legday; exercise = Leg Extension; sets = 3; reps = 6; kg = 43.5; notes = Lett; }] I want to get only the date, for each workout. I have tried some different things, and the closest I've got, was using this: var remoteIndexPath = NSIndexPath(row: 0, section: 0) func didSelectDayView(_ dayView: DayView, animationDidFinish: Bool) { let row = result[remoteIndexPath.row] for i in result.indices { // Prøv dette i stedet for: for i in 0 ..< Results.count { print(result[remoteIndexPath.row].date) } } The problem is that it only prints out the first value 13 times: Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Optional(2019-03-06 22:18:41 +0000) Any ideas/tips?
You can try let res = result.filter { compareDate(date1:$0.date, date2:savedDate) } print(res)
I think you are asking how to iterate over an array of objects and return the date property? I don't know what your workout object looks like so I made one up class Workout { var date = "" var name = "" init(aDate: String, aName: String) { self.date = aDate self.name = aName } } var results:[Workout] = [] let w0 = Workout(aDate: "2019-03-06", aName: "Legday") let w1 = Workout(aDate: "2019-02-24", aName: "bvjc") let w2 = Workout(aDate: "2019-02-22", aName: "Chest") results.append(w0) results.append(w1) results.append(w2) let allDates = results.map{ $0.date } //creates an array of just the dates print(allDates) and the output is ["2019-03-06", "2019-02-24", "2019-02-22"]
How to convert string time to unix?
I'm creating an administrating tool and I need to convert string type like that: '1y2m3d4h5mi6s' to unixtime (seconds) in Lua. How can I make this? I expect the output of StrToTime("1d") to be 86400.
function StrToTime(time_as_string) local dt = {year = 2000, month = 1, day = 1, hour = 0, min = 0, sec = 0} local time0 = os.time(dt) local units = {y="year", m="month", d="day", h="hour", mi="min", s="sec", w="7day"} for num, unit in time_as_string:gmatch"(%d+)(%a+)" do local factor, field = units[unit]:match"^(%d*)(%a+)$" dt[field] = dt[field] + tonumber(num) * (tonumber(factor) or 1) end return os.time(dt) - time0 end print(StrToTime("1d")) -- 86400 print(StrToTime("1d1s")) -- 86401 print(StrToTime("1w1d1s")) -- 691201 print(StrToTime("1w1d")) -- 691200
Code snippet converting your date string to seconds local testDate = '2019y2m8d15h0mi42s' local seconds = string.gsub( testDate, '(%d+)y(%d+)m(%d+)d(%d+)h(%d+)mi(%d+)s', function(y, mon, d, h, min, s) return os.time{ year = tonumber(y), month = tonumber(mon), day = tonumber(d), hour = tonumber(h), min = tonumber(min), sec = tonumber(s) } end ) print(seconds) You can also write a local function, I think it's a bit better to read. local function printTime(y, mon, d, h, min, s) local res = os.time{ year = tonumber(y), month = tonumber(mon), day = tonumber(d), hour = tonumber(h), min = tonumber(min), sec = tonumber(s) } return res end local testDate = '2019y2m8d15h0mi42s' local seconds = string.gsub( testDate, '(%d+)y(%d+)m(%d+)d(%d+)h(%d+)mi(%d+)s', printTime ) print(seconds)
Axibase startime and endtime not working
Trying to make a portal that only shows 20 min of an outage time. Can't get startime to work. Tried 2 different formats. Always starting from Jan 1 1970. Please advise. [configuration] title = ECP_PROD_PEAKVIEW width-units = 6 height-units = 8 offset-right = 50 update-interval = 15 display-date = true startime = 2017-12-21 09:20:00 endtime = 2017-12-21 09:45:00 auto-scale = true auto-period = true entity = dnvrco-ecp01 endtime = now alert-style = fill: red; stroke: red and [configuration] title = ECP_PROD_PEAKVIEW width-units = 6 height-units = 8 offset-right = 50 update-interval = 15 display-date = true startime = 2017-12-21T09:20:00Z endtime = 2017-12-21T09:45:00Z auto-scale = true auto-period = true entity = dnvrco-ecp01 endtime = now alert-style = fill: red; stroke: red
Looks like the startime setting is missing a t. starttime = 2017-12-21 09:20:00 You can add dash symbols to make parameters more reedable: start-time = 2017-12-21 09:20:00 end-time = 2017-12-21 09:45:00 Example: https://apps.axibase.com/chartlab/47fbef76 I would also remove the duplicate endtime setting in the [configuration] section. In case you need to show the most recent 20 minutes, just specify the timespan and remove start-time and end-time altogether. Both start-time and end-time settings accept calendar expressions. start-time = previous_hour end-time = current_hour Or, alternatively: timespan = 1 hour end-time = current_hour
Confusion about NSTimeZone.secondsFromGMT
I am developing an app that has a feature to enter dark/night mode during night hours automatically. The app asks for the user location and determines the sunrise/sunset hour (in Universal Time) using this algorithm. The only step that is not clear is to convert from UT to local time, since this is not explained in the algorithm. Say I get a sunrise time of 8.5 (8:30 in the morning UT). How could I convert it to user's local time to check if it's day or night? Or equivalently, how could I convert user's local time to UT in order to be able to compare them? So far I've tried to use NSCalendar to get the NSDateComponents of the current date (NSDate()). One of these components is a NSTimeZone? from which I can get the secondsFromGMT. Something like this: let dateComponents = NSCalendar.currentCalendar().components([.TimeZone], fromDate: NSDate()) let localOffset = Double(dateComponents.timeZone?.secondsFromGMT ?? 0)/3600 where localOffset should be the time difference (in hours) from UT (i.e. GMT if I am right) to local time, defaulting to 0 if dateComponents.timeZone == nil (I don't know under which situations this could happen). The problem is that I get the same localOffset for now than for 6 months in the future (when the daylight saving time will be different than it is now at my location, Spain). Does this mean that I need to use the properties daylightSavingTime and/or daylightSavingTimeOffset together with secondsFromGMT? Doesn't secondsFromGMT itself account for this? Things get even more confusing to me when I read the results from the algorithm. The sun setting hour (in local time) is exactly the one given by Google, but the sun rising hour is one hour ahead of what Google says (for my location and date). I share with you the whole Swift implementation of the algorithm hoping that it can help someone spot what's that I'm doing wrong. import Foundation import CoreLocation enum SunriseSunsetZenith: Double { case Official = 90.83 case Civil = 96 case Nautical = 102 case Astronomical = 108 } func sunriseSunsetHoursForLocation(coordinate: CLLocationCoordinate2D, atDate date: NSDate = NSDate(), zenith: SunriseSunsetZenith = .Civil) -> (sunrise: Double, sunset: Double) { // Initial values (will be changed later) var sunriseTime = 7.5 var sunsetTime = 19.5 // Get the longitude and latitude let latitude = coordinate.latitude let longitude = coordinate.longitude // Get the day, month, year and local offset let dateComponents = NSCalendar.currentCalendar().components([.Day, .Month, .Year, .TimeZone], fromDate: date) let day = Double(dateComponents.day) let month = Double(dateComponents.month) let year = Double(dateComponents.year) let localOffset = Double(dateComponents.timeZone?.daylightSavingTimeOffset ?? 0)/3600 // Calculate the day of the year let N1 = floor(275*month/9) let N2 = floor((month + 9)/12) let N3 = 1 + floor((year - 4*floor(year/4) + 2)/3) let dayOfYear = N1 - N2*N3 + day - 30 for i in 0...1 { // Convert the longitude to hour value and calculate an approximate time let longitudeHour = longitude/15 let t = dayOfYear + ((i == 0 ? 6.0 : 18.0) - longitudeHour)/24 // Calculate the Sun's mean anomaly let M = 0.9856*t - 3.289 // Calculate the Sun's true longitude var L = M + 1.916*sind(M) + 0.020*sind(2*M) + 282.634 L %= 360 // Calculate the Sun's right ascension var RA = atand(0.91764 * tand(L)) RA %= 360 let Lquadrant = (floor(L/90))*90 let RAquadrant = (floor(RA/90))*90 RA += Lquadrant - RAquadrant RA /= 15 // Calculate the Sun's declination let sinDec = 0.39782*sind(L) let cosDec = cosd(asind(sinDec)) // Calculate the Sun's local hour angle let cosH = (cosd(zenith.rawValue) - sinDec*sind(latitude))/(cosDec*cosd(latitude)) if cosH > 1 { // The sun never rises on this location (on the specified date) sunriseTime = Double.infinity sunsetTime = -Double.infinity } else if cosH < -1 { // The sun never sets on this location (on the specified date) sunriseTime = -Double.infinity sunsetTime = Double.infinity } else { // Finish calculating H and convert into hours var H = ( i == 0 ? 360.0 : 0.0 ) + ( i == 0 ? -1.0 : 1.0 )*acosd(cosH) H /= 15 // Calculate local mean time of rising/setting let T = H + RA - 0.06571*t - 6.622 // Adjust back to UTC let UT = T - longitudeHour // Convert UT value to local time zone of latitude/longitude let localT = UT + localOffset if i == 0 { // Add 24 and modulo 24 to be sure that the results is between 0..<24 sunriseTime = (localT + 24)%24 } else { sunsetTime = (localT + 24)%24 } } } return (sunriseTime, sunsetTime) } func sind(valueInDegrees: Double) -> Double { return sin(valueInDegrees*M_PI/180) } func cosd(valueInDegrees: Double) -> Double { return cos(valueInDegrees*M_PI/180) } func tand(valueInDegrees: Double) -> Double { return tan(valueInDegrees*M_PI/180) } func asind(valueInRadians: Double) -> Double { return asin(valueInRadians)*180/M_PI } func acosd(valueInRadians: Double) -> Double { return acos(valueInRadians)*180/M_PI } func atand(valueInRadians: Double) -> Double { return atan(valueInRadians)*180/M_PI } Ans this is how I use the function to determine if it's night or not: let latitude = ... let longitude = ... let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) let (sunriseHour, sunsetHour) = sunriseSunsetHoursForLocation(coordinate) let componetns = NSCalendar.currentCalendar().components([.Hour, .Minute], fromDate: NSDate()) let currentHour = Double(componetns.hour) + Double(componetns.minute)/60 let isNight = currentHour < sunriseHour || currentHour > sunsetHour
I'm not sure why your code to get the offset isn't working (I got the same result). But there's a simpler solution that does work. Just ask the local time zone, using secondsFromGMTForDate. With dates six months apart I get different results: let now = NSDate() let future = NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.Month, value: 6, toDate: now, options: NSCalendarOptions(rawValue: 0))! let nowOffset = NSTimeZone.localTimeZone().secondsFromGMTForDate(now)/3600 let futureOffset = NSTimeZone.localTimeZone().secondsFromGMTForDate(future)/3600