由于之前一直从事国内项目的开发,所以项目中并不会牵扯到国际化以及时间转化问题,最近开发了一个国际项目,其中遇到了许多关于app国际化和时区转换的问题。有关于国际化的问题,不在赘述,今天主要记录一下关于时区的一些笔记。
时区的概念:
时区是地球上的区域使用同一个时间定义。以前,人们通过观察太阳的位置(时角)决定时间,这就使得不同纬度地方的时间有所不同(地方时)。1863年,首次使用时区的概念。时区通过设立一个区域的标准时间部分地解决了这个问题。
时区的划分:
理论时区以被15整除的子午线(0度经线)为中心,向东西两侧延伸7.5度,即每15°划分一个时区,这是理论时区。理论时区的时间采用其中央经线(或标准经线)的地方时。所以每差一个时区,区时相差一个小时,相差多少个时区,就相差多少个小时。
世界理论时区的数量:
按照之前的时区划分阐述,世界上一共存在24个时区,那么这24个时区之间的时间关系是怎样的呢?由于地球自转方向是由西向东的,那么我们其实可以简单的理解身处于东边的人始终比西边的人早看到太阳,那么相差一个时区,东面的时区就会西面的时区早一个小时,但是这样怎么区分日期呢?好像东边时间总是比西边的时间早?为了避免日期的混淆,所以国际约定了International Date Line,即国际日期变更线。
国际日期变更线:
国际日期变更线为180度经线,也就是日界线,人为绕开了一些岛屿和陆地,基本从海洋穿过。为什么会划出国际日期变更线呢?
国际日期变更线的原理:
时区划分后,从本初子午线向东,每过一个时区,时钟需要拨快1h,那么到了180°经线的时候,时间就快了12h, 那么继续向东的情况下,始终是否需要继续拨快呢?答案是肯定的,但是为了避免日期的混淆,这时候从东向西越过180°经线的时候,日期需要加一天,如果180°经线的东边是24时,那么180度经线的西边就是下一天的0时。同理,如果180°经线的西边是0时,那么从西向东越过180°经线,时间就变成了前一天的24时。一个更具体的例子:如果180°经线的东边是2017年7月20日正午12时整,那么180°经线的西边就是2017年7月21日12时。,不要问我为什么这样划分,这是国际约定的时期人为界定方法,是为了解决时间的落差问题,可以自己去维基科普。
基本的日期,时区划分,以及时间转换原理已经做了大概的描述,如果想要进一步深究这个问题,可以复习一下初中的地理课本,或者直接去维基百科查询相关介绍。
下面介绍一下在iOS的具体开发中,常用的时区问题,时间转换问题(以Swift开发为例)
附上各国主要地区时区列表的google链接
废话不多说了,直接上代码:
import Foundation
class DateUtilities {
//GreenWitch Mean Time (GMT)
static let timeZoneZulu: TimeZone = {
// +0:00
if let timeZone = TimeZone(secondsFromGMT:0) {
return timeZone
} else {
//assertionFailure()
return TimeZone.autoupdatingCurrent
}
}()
//TimeZoneLocal (Shanghai)
static let timeZoneLocal: TimeZone = {
// +8:00
if let timeZone = TimeZone(abbreviation:"UTC+8") {
return timeZone
} else {
//assertionFailure()
return TimeZone.autoupdatingCurrent
}
}()
//Calender
static let calendar: Calendar = {
//Gregorian
var result = Calendar(identifier: Calendar.Identifier.gregorian)
result.timeZone = DateUtilities.timeZoneLocal
return result
}()
//DateFormatter
//2017-07-25 14:19:54:056 +08:00
static let dateFormatter1: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss:SSS ZZZZZ"
dateFormatter.timeZone = DateUtilities.timeZoneLocal
dateFormatter.locale = DateUtilities.localeDetermin
return dateFormatter
}()
//2017-07-25 06:20:51 Z
static let dateFormatter2: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZZ"
dateFormatter.timeZone = DateUtilities.timeZoneZulu
return dateFormatter
}()
//2016-01-01
static let dateFormatter3: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.timeZone = DateUtilities.timeZoneLocal
return dateFormatter
}()
//Tuesday, Jul 25, 2017
static let dateFormatter4: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
dateFormatter.timeZone = DateUtilities.timeZoneLocal
dateFormatter.locale = DateUtilities.localeDetermin
return dateFormatter
}()
//2:34 PM
static let dateFormatter5: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "h:mm a"
dateFormatter.timeZone = DateUtilities.timeZoneLocal
dateFormatter.locale = DateUtilities.localeDetermin
return dateFormatter
}()
//change locale
static let localeDetermin: Locale = {
let locale = Locale.init(identifier: "zh-Hans")
return locale
}()
//change time from timeStamp to foramt string
static func transferTimeStampToformatString(timeStamp: String) -> String {
let timeStamp = CFStringGetDoubleValue(timeStamp as CFString)
let date = Date(timeIntervalSince1970:timeStamp)
let dateString = DateUtilities.dateFormatter4.string(from: date)
return dateString
}
}
下面是一些测试的print:
//Get current time(Green Witch)
print(Date())
//Get current local time
let dateStringLocal = DateUtilities.dateFormatter1.string(from: Date())
print(dateStringLocal)
//Get current Zulu time
let dateStringZulu = DateUtilities.dateFormatter2.string(from: Date())
print(dateStringZulu)
let dateStringShort = DateUtilities.dateFormatter5.string(from: Date())
print(dateStringShort)
//timeStamp
let dateStringFromTimeStamp = DateUtilities.transferTimeStampToformatString(timeStamp: "\(1500967966)")
print(dateStringFromTimeStamp)
其实关于时区的划分和概念的部分,不需要去深究,通过代码,程序会帮助我们自动转化,如果有兴趣的的话,可以适当了解下这部分知识,肯定会加深你对全球时间的理解。以上的代码应该可以满足平常的国际化时间转化相关的,以及本地化相关的功能。
如果有任何不当之处,还请指出,谢谢!