datetime: adjust timezone code

- update timezone interface
- adjust datetime code
- fixed sync time error when timezone changed

tower: https://tower.im/projects/8f19f0bf0e754f0b82ef2c24bc230973/todos/02bd7e1d22f147578173f12497e8db48/
tower: https://tower.im/projects/8f19f0bf0e754f0b82ef2c24bc230973/todos/11511ba41be74f0f968058a8cccf2d83/
Change-Id: I27deb7eb996ce22dd6daf0fc14b7878b3cde4914
This commit is contained in:
jouyouyun 2014-11-11 17:47:45 +08:00 committed by snyh
parent 6f8a823128
commit 35b9e3d6c9
34 changed files with 2339 additions and 2255 deletions

View File

@ -74,8 +74,7 @@ install: build translate
cp misc/schemas/* ${DESTDIR}${PREFIX}/share/glib-2.0/schemas
mkdir -pv ${DESTDIR}${PREFIX}/share/dde-daemon
cp -r misc/lang ${DESTDIR}${PREFIX}/share/dde-daemon/
cp -r misc/template ${DESTDIR}${PREFIX}/share/dde-daemon/
cp -r misc/usr/share/dde-daemon/* ${DESTDIR}${PREFIX}/share/dde-daemon/
mkdir -pv ${DESTDIR}${PREFIX}/bin
cp misc/tool/wireless_script*.sh ${DESTDIR}${PREFIX}/bin/wireless-script

View File

@ -1,512 +0,0 @@
package datetime
var noUnderlineList = []string{
"Africa/Porto-Novo",
"America/Blanc-Sablon",
"America/Port-au-Prince",
"Canada/East-Saskatchewan",
"US/East-Indiana",
"US/Indiana-Starke",
"US/Pacific-New",
}
/*
var zoneCityInfo = []string{
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
"Africa/Algiers",
"Africa/Asmara",
"Africa/Asmera",
"Africa/Bamako",
"Africa/Bangui",
"Africa/Banjul",
"Africa/Bissau",
"Africa/Blantyre",
"Africa/Brazzaville",
"Africa/Bujumbura",
"Africa/Cairo",
"Africa/Casablanca",
"Africa/Ceuta",
"Africa/Conakry",
"Africa/Dakar",
"Africa/Dar_es_Salaam",
"Africa/Djibouti",
"Africa/Douala",
"Africa/El_Aaiun",
"Africa/Freetown",
"Africa/Gaborone",
"Africa/Harare",
"Africa/Johannesburg",
"Africa/Juba",
"Africa/Kampala",
"Africa/Khartoum",
"Africa/Kigali",
"Africa/Kinshasa",
"Africa/Lagos",
"Africa/Libreville",
"Africa/Lome",
"Africa/Luanda",
"Africa/Lubumbashi",
"Africa/Lusaka",
"Africa/Malabo",
"Africa/Maputo",
"Africa/Maseru",
"Africa/Mbabane",
"Africa/Mogadishu",
"Africa/Monrovia",
"Africa/Nairobi",
"Africa/Ndjamena",
"Africa/Niamey",
"Africa/Nouakchott",
"Africa/Ouagadougou",
"Africa/Porto-Novo",
"Africa/Sao_Tome",
"Africa/Timbuktu",
"Africa/Tripoli",
"Africa/Tunis",
"Africa/Windhoek",
"America/Adak",
"America/Anchorage",
"America/Anguilla",
"America/Antigua",
"America/Araguaina",
"America/Argentina/Buenos_Aires",
"America/Argentina/Catamarca",
"America/Argentina/ComodRivadavia",
"America/Argentina/Cordoba",
"America/Argentina/Jujuy",
"America/Argentina/La_Rioja",
"America/Argentina/Mendoza",
"America/Argentina/Rio_Gallegos",
"America/Argentina/Salta",
"America/Argentina/San_Juan",
"America/Argentina/San_Luis",
"America/Argentina/Tucuman",
"America/Argentina/Ushuaia",
"America/Aruba",
"America/Asuncion",
"America/Atikokan",
"America/Atka",
"America/Bahia",
"America/Bahia_Banderas",
"America/Barbados",
"America/Belem",
"America/Belize",
"America/Blanc-Sablon",
"America/Boa_Vista",
"America/Bogota",
"America/Boise",
"America/Buenos_Aires",
"America/Cambridge_Bay",
"America/Campo_Grande",
"America/Cancun",
"America/Caracas",
"America/Catamarca",
"America/Cayenne",
"America/Cayman",
"America/Chicago",
"America/Chihuahua",
"America/Coral_Harbour",
"America/Cordoba",
"America/Costa_Rica",
"America/Creston",
"America/Cuiaba",
"America/Curacao",
"America/Danmarkshavn",
"America/Dawson",
"America/Dawson_Creek",
"America/Denver",
"America/Detroit",
"America/Dominica",
"America/Edmonton",
"America/Eirunepe",
"America/El_Salvador",
"America/Ensenada",
"America/Fort_Wayne",
"America/Fortaleza",
"America/Glace_Bay",
"America/Godthab",
"America/Goose_Bay",
"America/Grand_Turk",
"America/Grenada",
"America/Guadeloupe",
"America/Guatemala",
"America/Guayaquil",
"America/Guyana",
"America/Halifax",
"America/Havana",
"America/Hermosillo",
"America/Indiana/Indianapolis",
"America/Indiana/Knox",
"America/Indiana/Marengo",
"America/Indiana/Petersburg",
"America/Indiana/Tell_City",
"America/Indiana/Vevay",
"America/Indiana/Vincennes",
"America/Indiana/Winamac",
"America/Indianapolis",
"America/Inuvik",
"America/Iqaluit",
"America/Jamaica",
"America/Jujuy",
"America/Juneau",
"America/Kentucky/Louisville",
"America/Kentucky/Monticello",
"America/Knox_IN",
"America/Kralendijk",
"America/La_Paz",
"America/Lima",
"America/Los_Angeles",
"America/Louisville",
"America/Lower_Princes",
"America/Maceio",
"America/Managua",
"America/Manaus",
"America/Marigot",
"America/Martinique",
"America/Matamoros",
"America/Mazatlan",
"America/Mendoza",
"America/Menominee",
"America/Merida",
"America/Metlakatla",
"America/Mexico_City",
"America/Miquelon",
"America/Moncton",
"America/Monterrey",
"America/Montevideo",
"America/Montreal",
"America/Montserrat",
"America/Nassau",
"America/New_York",
"America/Nipigon",
"America/Nome",
"America/Noronha",
"America/North_Dakota/Beulah",
"America/North_Dakota/Center",
"America/North_Dakota/New_Salem",
"America/Ojinaga",
"America/Panama",
"America/Pangnirtung",
"America/Paramaribo",
"America/Phoenix",
"America/Port_of_Spain",
"America/Port-au-Prince",
"America/Porto_Acre",
"America/Porto_Velho",
"America/Puerto_Rico",
"America/Rainy_River",
"America/Rankin_Inlet",
"America/Recife",
"America/Regina",
"America/Resolute",
"America/Rio_Branco",
"America/Rosario",
"America/Santa_Isabel",
"America/Santarem",
"America/Santiago",
"America/Santo_Domingo",
"America/Sao_Paulo",
"America/Scoresbysund",
"America/Shiprock",
"America/Sitka",
"America/St_Barthelemy",
"America/St_Johns",
"America/St_Kitts",
"America/St_Lucia",
"America/St_Thomas",
"America/St_Vincent",
"America/Swift_Current",
"America/Tegucigalpa",
"America/Thule",
"America/Thunder_Bay",
"America/Tijuana",
"America/Toronto",
"America/Tortola",
"America/Vancouver",
"America/Virgin",
"America/Whitehorse",
"America/Winnipeg",
"America/Yakutat",
"America/Yellowknife",
"Antarctica/Casey",
"Antarctica/Davis",
"Antarctica/DumontDUrville",
"Antarctica/Macquarie",
"Antarctica/Mawson",
"Antarctica/McMurdo",
"Antarctica/Palmer",
"Antarctica/Rothera",
"Antarctica/South_Pole",
"Antarctica/Syowa",
"Antarctica/Vostok",
"Arctic/Longyearbyen",
"Asia/Aden",
"Asia/Almaty",
"Asia/Amman",
"Asia/Anadyr",
"Asia/Aqtau",
"Asia/Aqtobe",
"Asia/Ashgabat",
"Asia/Ashkhabad",
"Asia/Baghdad",
"Asia/Bahrain",
"Asia/Baku",
"Asia/Bangkok",
"Asia/Beirut",
"Asia/Bishkek",
"Asia/Brunei",
"Asia/Calcutta",
"Asia/Choibalsan",
"Asia/Chongqing",
"Asia/Chungking",
"Asia/Colombo",
"Asia/Dacca",
"Asia/Damascus",
"Asia/Dhaka",
"Asia/Dili",
"Asia/Dubai",
"Asia/Dushanbe",
"Asia/Gaza",
"Asia/Harbin",
"Asia/Hebron",
"Asia/Ho_Chi_Minh",
"Asia/Hong_Kong",
"Asia/Hovd",
"Asia/Irkutsk",
"Asia/Istanbul",
"Asia/Jakarta",
"Asia/Jayapura",
"Asia/Jerusalem",
"Asia/Kabul",
"Asia/Kamchatka",
"Asia/Karachi",
"Asia/Kashgar",
"Asia/Kathmandu",
"Asia/Katmandu",
"Asia/Kolkata",
"Asia/Krasnoyarsk",
"Asia/Kuala_Lumpur",
"Asia/Kuching",
"Asia/Kuwait",
"Asia/Macao",
"Asia/Macau",
"Asia/Magadan",
"Asia/Makassar",
"Asia/Manila",
"Asia/Muscat",
"Asia/Nicosia",
"Asia/Novokuznetsk",
"Asia/Novosibirsk",
"Asia/Omsk",
"Asia/Oral",
"Asia/Phnom_Penh",
"Asia/Pontianak",
"Asia/Pyongyang",
"Asia/Qatar",
"Asia/Qyzylorda",
"Asia/Rangoon",
"Asia/Riyadh",
"Asia/Saigon",
"Asia/Sakhalin",
"Asia/Samarkand",
"Asia/Seoul",
"Asia/Shanghai",
"Asia/Singapore",
"Asia/Taipei",
"Asia/Tashkent",
"Asia/Tbilisi",
"Asia/Tehran",
"Asia/Tel_Aviv",
"Asia/Thimbu",
"Asia/Thimphu",
"Asia/Tokyo",
"Asia/Ujung_Pandang",
"Asia/Ulaanbaatar",
"Asia/Ulan_Bator",
"Asia/Urumqi",
"Asia/Vientiane",
"Asia/Vladivostok",
"Asia/Yakutsk",
"Asia/Yekaterinburg",
"Asia/Yerevan",
"Atlantic/Azores",
"Atlantic/Bermuda",
"Atlantic/Canary",
"Atlantic/Cape_Verde",
"Atlantic/Faeroe",
"Atlantic/Faroe",
"Atlantic/Jan_Mayen",
"Atlantic/Madeira",
"Atlantic/Reykjavik",
"Atlantic/South_Georgia",
"Atlantic/St_Helena",
"Atlantic/Stanley",
"Australia/ACT",
"Australia/Adelaide",
"Australia/Brisbane",
"Australia/Broken_Hill",
"Australia/Canberra",
"Australia/Currie",
"Australia/Darwin",
"Australia/Eucla",
"Australia/Hobart",
"Australia/LHI",
"Australia/Lindeman",
"Australia/Lord_Howe",
"Australia/Melbourne",
"Australia/North",
"Australia/NSW",
"Australia/Perth",
"Australia/Queensland",
"Australia/South",
"Australia/Sydney",
"Australia/Tasmania",
"Australia/Victoria",
"Australia/West",
"Australia/Yancowinna",
"Brazil/Acre",
"Brazil/DeNoronha",
"Brazil/East",
"Brazil/West",
"Canada/Atlantic",
"Canada/Central",
"Canada/Eastern",
"Canada/East-Saskatchewan",
"Canada/Mountain",
"Canada/Newfoundland",
"Canada/Pacific",
"Canada/Saskatchewan",
"Canada/Yukon",
"Chile/Continental",
"Chile/EasterIsland",
"Europe/Amsterdam",
"Europe/Andorra",
"Europe/Athens",
"Europe/Belfast",
"Europe/Belgrade",
"Europe/Berlin",
"Europe/Bratislava",
"Europe/Brussels",
"Europe/Bucharest",
"Europe/Budapest",
"Europe/Chisinau",
"Europe/Copenhagen",
"Europe/Dublin",
"Europe/Gibraltar",
"Europe/Guernsey",
"Europe/Helsinki",
"Europe/Isle_of_Man",
"Europe/Istanbul",
"Europe/Jersey",
"Europe/Kaliningrad",
"Europe/Kiev",
"Europe/Lisbon",
"Europe/Ljubljana",
"Europe/London",
"Europe/Luxembourg",
"Europe/Madrid",
"Europe/Malta",
"Europe/Mariehamn",
"Europe/Minsk",
"Europe/Monaco",
"Europe/Moscow",
"Europe/Nicosia",
"Europe/Oslo",
"Europe/Paris",
"Europe/Podgorica",
"Europe/Prague",
"Europe/Riga",
"Europe/Rome",
"Europe/Samara",
"Europe/San_Marino",
"Europe/Sarajevo",
"Europe/Simferopol",
"Europe/Skopje",
"Europe/Sofia",
"Europe/Stockholm",
"Europe/Tallinn",
"Europe/Tirane",
"Europe/Tiraspol",
"Europe/Uzhgorod",
"Europe/Vaduz",
"Europe/Vatican",
"Europe/Vienna",
"Europe/Vilnius",
"Europe/Volgograd",
"Europe/Warsaw",
"Europe/Zagreb",
"Europe/Zaporozhye",
"Europe/Zurich",
"Indian/Antananarivo",
"Indian/Chagos",
"Indian/Christmas",
"Indian/Cocos",
"Indian/Comoro",
"Indian/Kerguelen",
"Indian/Mahe",
"Indian/Maldives",
"Indian/Mauritius",
"Indian/Mayotte",
"Indian/Reunion",
"Mexico/BajaNorte",
"Mexico/BajaSur",
"Mexico/General",
"Pacific/Apia",
"Pacific/Auckland",
"Pacific/Chatham",
"Pacific/Chuuk",
"Pacific/Easter",
"Pacific/Efate",
"Pacific/Enderbury",
"Pacific/Fakaofo",
"Pacific/Fiji",
"Pacific/Funafuti",
"Pacific/Galapagos",
"Pacific/Gambier",
"Pacific/Guadalcanal",
"Pacific/Guam",
"Pacific/Honolulu",
"Pacific/Johnston",
"Pacific/Kiritimati",
"Pacific/Kosrae",
"Pacific/Kwajalein",
"Pacific/Majuro",
"Pacific/Marquesas",
"Pacific/Midway",
"Pacific/Nauru",
"Pacific/Niue",
"Pacific/Norfolk",
"Pacific/Noumea",
"Pacific/Pago_Pago",
"Pacific/Palau",
"Pacific/Pitcairn",
"Pacific/Pohnpei",
"Pacific/Ponape",
"Pacific/Port_Moresby",
"Pacific/Rarotonga",
"Pacific/Saipan",
"Pacific/Samoa",
"Pacific/Tahiti",
"Pacific/Tarawa",
"Pacific/Tongatapu",
"Pacific/Truk",
"Pacific/Wake",
"Pacific/Wallis",
"Pacific/Yap",
"US/Alaska",
"US/Aleutian",
"US/Arizona",
"US/Central",
"US/Eastern",
"US/East-Indiana",
"US/Hawaii",
"US/Indiana-Starke",
"US/Michigan",
"US/Mountain",
"US/Pacific",
"US/Pacific-New",
"US/Samoa",
}
*/

View File

@ -1,213 +1,122 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
import (
"dbus/com/deepin/api/setdatetime"
"github.com/howeyc/fsnotify"
"pkg.linuxdeepin.com/lib/dbus"
"io/ioutil"
"pkg.linuxdeepin.com/dde-daemon/datetime/ntp"
"pkg.linuxdeepin.com/dde-daemon/datetime/timezone"
. "pkg.linuxdeepin.com/dde-daemon/datetime/utils"
"pkg.linuxdeepin.com/lib/dbus/property"
. "pkg.linuxdeepin.com/lib/gettext"
"pkg.linuxdeepin.com/lib/gio-2.0"
"pkg.linuxdeepin.com/lib/log"
"strings"
)
const (
_DATE_TIME_DEST = "com.deepin.daemon.DateAndTime"
_DATE_TIME_PATH = "/com/deepin/daemon/DateAndTime"
_DATA_TIME_IFC = "com.deepin.daemon.DateAndTime"
dbusSender = "com.deepin.daemon.DateAndTime"
dbusPath = "/com/deepin/daemon/DateAndTime"
dbusIFC = "com.deepin.daemon.DateAndTime"
_DATE_TIME_SCHEMA = "com.deepin.dde.datetime"
_TIME_ZONE_FILE = "/etc/timezone"
gsKeyAutoSetTime = "is-auto-set"
gsKey24Hour = "is-24hour"
gsKeyUTCOffset = "utc-offset"
gsKeyTimezoneList = "user-timezone-list"
gsKeyDSTOffset = "dst-offset"
defaultTimezone = "UTC"
defaultTimezoneFile = "/etc/timezone"
defaultUTCOffset = "+00:00"
)
var (
busConn *dbus.Conn
dateSettings = gio.NewSettings(_DATE_TIME_SCHEMA)
setDate *setdatetime.SetDateTime
zoneWatcher *fsnotify.Watcher
logger = log.NewLogger(_DATE_TIME_DEST)
changeLocaleFlag = false
)
type Manager struct {
AutoSetTime *property.GSettingsBoolProperty `access:"readwrite"`
type DateTime struct {
NTPEnabled *property.GSettingsBoolProperty `access:"readwrite"`
Use24HourDisplay *property.GSettingsBoolProperty `access:"readwrite"`
CurrentTimezone string
UserTimezoneList []string
CurrentLocale string
DSTOffset *property.GSettingsIntProperty `access:"readwrite"`
LocaleStatus func(bool, string)
UserTimezones *property.GSettingsStrvProperty
ntpRunning bool
quitChan chan bool
CurrentTimezone string
settings *gio.Settings
logger *log.Logger
}
func (op *Manager) SetDate(d string) (bool, error) {
ret, err := setDate.SetCurrentDate(d)
func NewDateTime(l *log.Logger) *DateTime {
date := &DateTime{}
err := InitSetDateTime()
if err != nil {
logger.Warning("Set Date - '%s' Failed: %s\n",
d, err)
return false, err
return nil
}
return ret, nil
}
func (op *Manager) SetTime(t string) (bool, error) {
ret, err := setDate.SetCurrentTime(t)
err = ntp.InitNtpModule()
if err != nil {
logger.Warning("Set Time - '%s' Failed: %s\n",
t, err)
return false, err
return nil
}
return ret, nil
date.logger = l
date.settings = gio.NewSettings("com.deepin.dde.datetime")
date.NTPEnabled = property.NewGSettingsBoolProperty(
date, "NTPEnabled",
date.settings, gsKeyAutoSetTime)
date.Use24HourDisplay = property.NewGSettingsBoolProperty(
date, "Use24HourDisplay",
date.settings, gsKey24Hour)
date.UserTimezones = property.NewGSettingsStrvProperty(
date, "UserTimezones",
date.settings, gsKeyTimezoneList)
date.DSTOffset = property.NewGSettingsIntProperty(
date, "DSTOffset",
date.settings, gsKeyDSTOffset)
date.setPropString(&date.CurrentTimezone,
"CurrentTimezone", getDefaultTimezone(defaultTimezoneFile))
date.AddUserTimezone(date.CurrentTimezone)
date.enableNTP(date.NTPEnabled.Get())
return date
}
func (op *Manager) TimezoneCityList() []zoneCityInfo {
return zoneInfos
func (date *DateTime) enableNTP(value bool) {
ntp.Enabled(value, date.CurrentTimezone)
}
func (op *Manager) SetTimeZone(zone string) bool {
_, err := setDate.SetTimezone(zone)
func getDefaultTimezone(config string) string {
zone, err := getTimezoneFromFile(config)
if err != nil || !timezone.IsZoneValid(zone) {
return defaultTimezone
}
return zone
}
func getTimezoneFromFile(filename string) (string, error) {
contents, err := ioutil.ReadFile(filename)
if err != nil {
logger.Warning("Set TimeZone - '%s' Failed: %s\n",
zone, err)
return false
return "", err
}
op.setPropName("CurrentTimezone")
return true
}
func (op *Manager) SyncNtpTime() bool {
return op.syncNtpTime()
}
func (op *Manager) AddUserTimezoneList(tz string) {
if !timezoneIsValid(tz) {
return
}
list := dateSettings.GetStrv("user-timezone-list")
if isElementExist(tz, list) {
return
}
list = append(list, tz)
dateSettings.SetStrv("user-timezone-list", list)
}
func (op *Manager) DeleteTimezoneList(tz string) {
if !timezoneIsValid(tz) {
return
}
list := dateSettings.GetStrv("user-timezone-list")
if !isElementExist(tz, list) {
return
}
tmp := []string{}
for _, v := range list {
if v == tz {
continue
}
tmp = append(tmp, v)
}
dateSettings.SetStrv("user-timezone-list", tmp)
}
func (op *Manager) SetLocale(locale string) {
if len(locale) < 1 {
return
}
if op.CurrentLocale == locale {
return
}
sendNotify("", "", Tr("Language is changing, please wait"))
setDate.GenLocale(locale)
changeLocaleFlag = true
op.CurrentLocale = locale
dbus.NotifyChange(op, "CurrentLocale")
}
func (m *Manager) GetLocaleList() []localeInfo {
return getLocaleInfoList()
}
func NewDateAndTime() *Manager {
m := &Manager{}
m.AutoSetTime = property.NewGSettingsBoolProperty(
m, "AutoSetTime",
dateSettings, "is-auto-set")
m.Use24HourDisplay = property.NewGSettingsBoolProperty(
m, "Use24HourDisplay",
dateSettings, "is-24hour")
m.setPropName("CurrentTimezone")
m.setPropName("UserTimezoneList")
m.setPropName("CurrentLocale")
m.listenSettings()
m.listenZone()
m.AddUserTimezoneList(m.CurrentTimezone)
m.ntpRunning = false
m.quitChan = make(chan bool)
return m
}
func Init() {
var err error
setDate, err = setdatetime.NewSetDateTime("com.deepin.api.SetDateTime", "/com/deepin/api/SetDateTime")
if err != nil {
logger.Error("New SetDateTime Failed:", err)
panic(err)
}
zoneWatcher, err = fsnotify.NewWatcher()
if err != nil {
logger.Error("New FS Watcher Failed:", err)
panic(err)
}
}
var _manager *Manager
func GetManager() *Manager {
if _manager == nil {
_manager = NewDateAndTime()
}
return _manager
}
func Start() {
logger.BeginTracing()
var err error
Init()
initZoneInfos()
date := GetManager()
err = dbus.InstallOnSession(date)
if err != nil {
logger.Fatal("Install Session DBus Failed:", err)
}
if date.AutoSetTime.Get() {
date.setAutoSetTime(true)
}
date.listenLocaleChange()
}
func Stop() {
zoneWatcher.Close()
dbus.UnInstallObject(GetManager())
logger.EndTracing()
lines := strings.Split(string(contents), "\n")
return lines[0], nil
}

View File

@ -1,6 +1,6 @@
/**
* Copyright (c) 2011 ~ 2013 Deepin, Inc.
* 2011 ~ 2013 jouyouyun
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
@ -22,140 +22,22 @@
package datetime
import (
"github.com/howeyc/fsnotify"
"os"
"pkg.linuxdeepin.com/lib/dbus"
"pkg.linuxdeepin.com/lib/gio-2.0"
dutils "pkg.linuxdeepin.com/lib/utils"
)
const (
DEFAULT_LOCALE = "en_US.UTF-8"
DEFAULT_ZONE = "UTC"
)
func (m *Manager) GetDBusInfo() dbus.DBusInfo {
func (date *DateTime) GetDBusInfo() dbus.DBusInfo {
return dbus.DBusInfo{
Dest: _DATE_TIME_DEST,
ObjectPath: _DATE_TIME_PATH,
Interface: _DATA_TIME_IFC,
Dest: dbusSender,
ObjectPath: dbusPath,
Interface: dbusIFC,
}
}
func (op *Manager) setAutoSetTime(auto bool) bool {
return op.enableNtp(auto)
}
func (op *Manager) setPropName(name string) {
switch name {
case "CurrentTimezone":
tz, _, err := setDate.GetTimezone()
if err != nil {
logger.Errorf("Get Time Zone Failed: %v\n", err)
return
}
if timezoneIsValid(tz) {
op.CurrentTimezone = tz
} else {
op.CurrentTimezone = DEFAULT_ZONE
op.SetTimeZone(DEFAULT_ZONE)
}
dbus.NotifyChange(op, name)
case "UserTimezoneList":
list := dateSettings.GetStrv("user-timezone-list")
tmp := []string{}
for _, l := range list {
if timezoneIsValid(l) {
tmp = append(tmp, l)
}
}
list = tmp
if !strArrayIsEqual(list, op.UserTimezoneList) {
op.UserTimezoneList = list
dbus.NotifyChange(op, "UserTimezoneList")
}
case "CurrentLocale":
valid := false
if locale, ok := getUserLocale(); ok {
if checkLocaleValid(locale) {
op.CurrentLocale = locale
valid = true
}
}
if !valid {
op.CurrentLocale, _ = getDefaultLocale()
if !checkLocaleValid(op.CurrentLocale) {
op.CurrentLocale = DEFAULT_LOCALE
}
op.SetLocale(op.CurrentLocale)
}
dbus.NotifyChange(op, name)
}
}
func (op *Manager) listenSettings() {
dateSettings.Connect("changed::is-auto-set", func(s *gio.Settings, name string) {
op.setAutoSetTime(s.GetBoolean("is-auto-set"))
})
dateSettings.Connect("changed::user-timezone-list", func(s *gio.Settings, name string) {
op.setPropName("UserTimezoneList")
})
}
func (op *Manager) listenZone() {
if ok := dutils.IsFileExist(_TIME_ZONE_FILE); !ok {
f, err := os.Create(_TIME_ZONE_FILE)
if err != nil {
logger.Errorf("Create '%s' Failed: %v\n",
_TIME_ZONE_FILE, err)
return
}
f.Close()
}
err := zoneWatcher.Watch(_TIME_ZONE_FILE)
if err != nil {
logger.Errorf("Watch '%s' Failed: %s\n", _TIME_ZONE_FILE, err)
func (date *DateTime) setPropString(handler *string, prop, value string) {
if *handler == value {
return
}
go func() {
defer zoneWatcher.Close()
for {
select {
case ev, ok := <-zoneWatcher.Event:
if !ok {
if zoneWatcher != nil {
zoneWatcher.RemoveWatch(_TIME_ZONE_FILE)
}
zoneWatcher, _ = fsnotify.NewWatcher()
zoneWatcher.Watch(_TIME_ZONE_FILE)
break
}
if ev == nil {
break
}
logger.Error("Watcher Event: ", ev)
if ev.IsDelete() {
zoneWatcher.Watch(_TIME_ZONE_FILE)
} else {
//if ev.IsModify() {
op.setPropName("CurrentTimezone")
//}
}
case err, ok := <-zoneWatcher.Error:
logger.Error("Watcher Event: ", err)
if !ok || err != nil {
if zoneWatcher != nil {
zoneWatcher.RemoveWatch(_TIME_ZONE_FILE)
}
zoneWatcher, _ = fsnotify.NewWatcher()
zoneWatcher.Watch(_TIME_ZONE_FILE)
break
}
}
}
}()
*handler = value
dbus.NotifyChange(date, prop)
}

44
datetime/datetime_test.go Normal file
View File

@ -0,0 +1,44 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
import (
C "launchpad.net/gocheck"
"testing"
)
type testWrapper struct{}
func init() {
C.Suite(&testWrapper{})
}
func Test(t *testing.T) {
C.TestingT(t)
}
func (*testWrapper) TestGetDefaultZone(c *C.C) {
c.Check(getDefaultTimezone("testdata/timezone"),
C.Equals, "Asia/Shanghai")
c.Check(getDefaultTimezone("testdata/xxx"),
C.Equals, "UTC")
}

32
datetime/handle_event.go Normal file
View File

@ -0,0 +1,32 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
import (
"pkg.linuxdeepin.com/lib/gio-2.0"
)
func (date *DateTime) listenGSettings() {
date.settings.Connect("changed::is-auto-set", func(s *gio.Settings, key string) {
date.enableNTP(date.settings.GetBoolean(key))
})
}

137
datetime/ifc.go Normal file
View File

@ -0,0 +1,137 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
import (
"fmt"
"pkg.linuxdeepin.com/dde-daemon/datetime/ntp"
"pkg.linuxdeepin.com/dde-daemon/datetime/timezone"
. "pkg.linuxdeepin.com/dde-daemon/datetime/utils"
)
var (
errInvalidDateArgs = fmt.Errorf("Invalid Date Argment")
)
func (date *DateTime) SetDate(year, month, day, hour, min, sec, nsec int32) error {
if !IsYearValid(year) || !IsMonthValid(month) ||
!IsDayValid(year, month, day) || !IsHourValid(hour) ||
!IsMinuteValid(min) || !IsSecondValid(sec) {
return errInvalidDateArgs
}
value := fmt.Sprintf("%v-%v-%v", year, month, day)
err := SetDate(value)
if err != nil {
Warningf(date.logger, "Set Date '%s' Failed: %v", value, err)
return err
}
value = fmt.Sprintf("%v:%v:%v", hour, min, sec)
err = SetTime(value)
if err != nil {
Warningf(date.logger, "Set Date '%s' Failed: %v", value, err)
return err
}
return nil
}
func (date *DateTime) SetTimezone(zone string) error {
err := timezone.SetTimezone(zone)
if err != nil {
Warning(date.logger, err)
return err
}
//date.settings.Reset(gsKeyDSTOffset)
date.setPropString(&date.CurrentTimezone,
"CurrentTimezone", zone)
date.AddUserTimezone(zone)
if date.NTPEnabled.Get() {
ntp.Timezone = zone
ok := ntp.SyncNetworkTime()
if !ok {
Warning(date.logger, "Sync Network Time Failed")
}
}
return nil
}
func (date *DateTime) AddUserTimezone(zone string) {
if !timezone.IsZoneValid(zone) {
Warning(date.logger, "Invalid zone:", zone)
return
}
list := date.settings.GetStrv(gsKeyTimezoneList)
if IsStrInList(zone, list) {
return
}
list = append(list, zone)
date.settings.SetStrv(gsKeyTimezoneList, list)
}
func (date *DateTime) DeleteUserTimezone(zone string) {
if !timezone.IsZoneValid(zone) {
Warning(date.logger, "Invalid zone:", zone)
return
}
list := date.settings.GetStrv(gsKeyTimezoneList)
var tmp []string
for _, s := range list {
if s == zone {
continue
}
tmp = append(tmp, s)
}
if len(tmp) == len(list) {
return
}
date.settings.SetStrv(gsKeyTimezoneList, tmp)
}
func (date *DateTime) GetZoneInfo(zone string) (timezone.ZoneInfo, error) {
info, err := timezone.GetZoneInfo(zone)
if info == nil {
return timezone.ZoneInfo{}, err
}
return *info, nil
}
func (date *DateTime) GetAllZoneSummary() []timezone.ZoneSummary {
return timezone.GetZoneSummaryList()
}
func (date *DateTime) Destroy() {
DestroySetDateTime()
ntp.FiniNtpModule()
date.settings.Unref()
}

View File

@ -1,195 +0,0 @@
package datetime
var (
localeList = []string{
"aa",
"ab",
"ae",
"af",
"am",
"ar",
"as",
"ast",
"ay",
"az",
"ba",
"be",
"be@latin",
"bg",
"bh",
"bi",
"bn",
"bn_IN",
"bo",
"br",
"bs",
"ca",
"ca@valencia",
"ce",
"ch",
"co",
"crh",
"cs",
"csb",
"cu",
"cv",
"cy",
"da",
"de",
"dsb",
"dz",
"el",
"en",
"en_GB",
"en_US",
"eo",
"es",
"et",
"eu",
"fa",
"fi",
"fj",
"fo",
"fr",
"fy",
"ga",
"gd",
"gl",
"gn",
"gu",
"gv",
"ha",
"he",
"hi",
"hne",
"ho",
"hr",
"hsb",
"hu",
"hy",
"hz",
"ia",
"id",
"ie",
"ik",
"io",
"is",
"it",
"iu",
"ja",
"jv",
"ka",
"ki",
"kk",
"kl",
"km",
"kn",
"ko",
"ks",
"ku",
"kv",
"kw",
"ky",
"la",
"lb",
"li",
"ln",
"lo",
"lt",
"lv",
"mai",
"mg",
"mh",
"mi",
"mk",
"ml",
"mn",
"mo",
"mr",
"ms",
"mt",
"my",
"na",
"nb",
"nd",
"nds",
"ne",
"ng",
"nl",
"nn",
"nr",
"nso",
"nv",
"ny",
"oc",
"om",
"or",
"os",
"pa",
"pi",
"pl",
"ps",
"pt",
"pt_BR",
"qu",
"rn",
"ro",
"rom",
"ru",
"rw",
"sa",
"sc",
"sd",
"se",
"sg",
"si",
"sk",
"sl",
"sm",
"sn",
"so",
"sq",
"sr",
"sr@ijekavian",
"sr@ijekavianlatin",
"sr@latin",
"ss",
"st",
"su",
"sv",
"sw",
"ta",
"te",
"tg",
"th",
"ti",
"tk",
"tn",
"to",
"tr",
"ts",
"tt",
"tw",
"ty",
"ug",
"uk",
"ur",
"uz",
"uz@cyrillic",
"ven",
"vi",
"vo",
"wa",
"wo",
"xh",
"x-test",
"yi",
"yo",
"za",
"zh",
"zh_CN",
"zh_HK",
"zh_TW",
"zu",
}
)

View File

@ -1,150 +0,0 @@
package datetime
var (
localeListMap = map[string]string{
"aa": "aa_DJ.UTF-8",
"af": "af_ZA.UTF-8",
"am": "am_ET",
"ar": "ar_EG.UTF-8",
"as": "as_IN",
"ast": "ast_ES.UTF-8",
"be": "be_BY.UTF-8",
"be@latin": "be_BY@latin",
"bg": "bg_BG.UTF-8",
"bn": "bn_BD",
"bn_IN": "bn_IN",
"bo": "bo_CN",
"br": "br_FR.UTF-8",
"bs": "bs_BA.UTF-8",
"ca": "ca_AD.UTF-8",
"ca@valencia": "ca_ES.UTF-8@valencia",
"crh": "crh_UA",
"cs": "cs_CZ.UTF-8",
"csb": "csb_PL",
"cv": "cv_RU",
"cy": "cy_GB.UTF-8",
"da": "da_DK.UTF-8",
"de": "de_DE.UTF-8",
"dz": "dz_BT",
"el": "el_GR.UTF-8",
//"en": "en_GB.UTF-8",
"en_GB": "en_GB.UTF-8",
"en_US": "en_US.UTF-8",
"eo": "eo_US.UTF-8",
"es": "es_ES.UTF-8",
"et": "et_EE.UTF-8",
"eu": "eu_ES.UTF-8",
"fa": "fa_IR",
"fi": "fi_FI.UTF-8",
"fo": "fo_FO.UTF-8",
"fr": "fr_FR.UTF-8",
"fy": "fy_DE",
"ga": "ga_IE.UTF-8",
"gd": "gd_GB.UTF-8",
"gl": "gl_ES.UTF-8",
"gu": "gu_IN",
"gv": "gv_GB.UTF-8",
"ha": "ha_NG",
"he": "he_IL.UTF-8",
"hi": "hi_IN",
"hne": "hne_IN",
"hr": "hr_HR.UTF-8",
"hsb": "hsb_DE.UTF-8",
"hu": "hu_HU.UTF-8",
"hy": "hy_AM",
"ia": "ia",
"id": "id_ID.UTF-8",
"ik": "ik_CA",
"is": "is_IS.UTF-8",
"it": "it_IT.UTF-8",
"iu": "iu_CA",
"ja": "ja_JP.UTF-8",
"ka": "ka_GE.UTF-8",
"kk": "kk_KZ.UTF-8",
"kl": "kl_GL.UTF-8",
"km": "km_KH",
"kn": "kn_IN",
"ko": "ko_KR.UTF-8",
"ks": "ks_IN",
"ku": "ku_TR.UTF-8",
"kw": "kw_GB.UTF-8",
"ky": "ky_KG",
"lb": "lb_LU",
"li": "li_BE",
"lo": "lo_LA",
"lt": "lt_LT.UTF-8",
"lv": "lv_LV.UTF-8",
"mai": "mai_IN",
"mg": "mg_MG.UTF-8",
"mh": "mhr_RU",
"mi": "mi_NZ.UTF-8",
"mk": "mk_MK.UTF-8",
"ml": "ml_IN",
"mn": "mn_MN",
"mr": "mr_IN",
"ms": "ms_MY.UTF-8",
"mt": "mt_MT.UTF-8",
"my": "my_MM",
"na": "nan_TW@latin",
"nb": "nb_NO.UTF-8",
"nds": "nds_DE",
"ne": "ne_NP",
"nl": "nl_NL.UTF-8",
"nn": "nn_NO.UTF-8",
"nr": "nr_ZA",
"nso": "nso_ZA",
"oc": "oc_FR.UTF-8",
"om": "om_KE.UTF-8",
"or": "or_IN",
"os": "os_RU",
"pa": "pa_IN",
"pl": "pl_PL.UTF-8",
"ps": "ps_AF",
"pt": "pt_PT.UTF-8",
"pt_BR": "pt_BR.UTF-8",
"ro": "ro_RO.UTF-8",
"ru": "ru_RU.UTF-8",
"rw": "rw_RW",
"sa": "sa_IN",
"sc": "sc_IT",
"sd": "sd_IN",
"se": "se_NO",
"si": "si_LK",
"sk": "sk_SK.UTF-8",
"sl": "sl_SI.UTF-8",
"so": "so_SO.UTF-8",
"sq": "sq_AL.UTF-8",
"sr": "sr_RS",
"sr@latin": "sr_RS@latin",
"ss": "ss_ZA",
"st": "st_ZA.UTF-8",
"sv": "sv_SE.UTF-8",
"sw": "sw_KE",
"ta": "ta_IN",
"te": "te_IN",
"tg": "tg_TJ.UTF-8",
"th": "th_TH.UTF-8",
"ti": "ti_ET",
"tk": "tk_TM",
"tn": "tn_ZA",
"tr": "tr_TR.UTF-8",
"ts": "ts_ZA",
"tt": "tt_RU",
"ug": "ug_CN",
"uk": "uk_UA.UTF-8",
"ur": "ur_IN",
"uz": "uz_UZ.UTF-8",
"uz@cyrillic": "uz_UZ@cyrillic",
"ven": "ve_ZA",
"vi": "vi_VN",
"wa": "wa_BE.UTF-8",
"wo": "wo_SN",
"xh": "xh_ZA.UTF-8",
"yi": "yi_US.UTF-8",
"yo": "yo_NG",
"zh_CN": "zh_CN.UTF-8",
"zh_HK": "zh_HK.UTF-8",
"zh_TW": "zh_TW.UTF-8",
"zu": "zu_ZA.UTF-8",
}
)

56
datetime/main.go Normal file
View File

@ -0,0 +1,56 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
import (
"pkg.linuxdeepin.com/lib/dbus"
"pkg.linuxdeepin.com/lib/log"
)
var _date *DateTime
func Start() {
var logger = log.NewLogger(dbusSender)
logger.BeginTracing()
_date = NewDateTime(logger)
if _date == nil {
logger.Error("Create DateTime Failed")
return
}
err := dbus.InstallOnSession(_date)
if err != nil {
logger.Error("Install DBus For DateTime Failed")
return
}
}
func Stop() {
if _date == nil {
return
}
_date.Destroy()
dbus.UnInstallObject(_date)
_date = nil
}

View File

@ -19,26 +19,69 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
package ntp
import (
"fmt"
"net"
"strconv"
. "pkg.linuxdeepin.com/dde-daemon/datetime/utils"
"sync"
"time"
)
const (
_NTP_HOST = "0.pool.ntp.org"
ntpHost = "0.pool.ntp.org"
)
func (obj *Manager) syncNtpTime() bool {
const (
NTPStateDisabled int32 = 0
NTPStateEnabled int32 = 1
)
// update time when timezone changed
var Timezone string
var (
stateLock sync.Mutex
ntpState int32
)
func InitNtpModule() error {
ntpState = NTPStateDisabled
return InitSetDateTime()
}
func FiniNtpModule() {
DestroySetDateTime()
}
func Enabled(enable bool, zone string) {
Timezone = zone
if enable {
if ntpState == NTPStateEnabled {
go SyncNetworkTime()
return
}
stateLock.Lock()
ntpState = NTPStateEnabled
stateLock.Unlock()
go syncThread()
} else {
stateLock.Lock()
ntpState = NTPStateDisabled
stateLock.Unlock()
}
return
}
func SyncNetworkTime() bool {
for i := 0; i < 10; i++ {
t, err := getNtpTime(obj.CurrentTimezone)
if err == nil && t != nil {
dStr, tStr := getDateTimeAny(t)
logger.Infof("Date: %s, Time: %s", dStr, tStr)
setDate.SetCurrentDate(dStr)
setDate.SetCurrentTime(tStr)
dStr, tStr, err := getDateTime()
if err == nil {
SetDate(dStr)
SetTime(tStr)
return true
}
}
@ -46,60 +89,39 @@ func (obj *Manager) syncNtpTime() bool {
return false
}
func (obj *Manager) syncNtpThread() {
func syncThread() {
for {
obj.syncNtpTime()
SyncNetworkTime()
timer := time.NewTimer(time.Minute * 10)
select {
case <-timer.C:
case <-obj.quitChan:
obj.ntpRunning = false
return
if ntpState == NTPStateDisabled {
return
}
}
}
}
func (obj *Manager) enableNtp(enable bool) bool {
if enable {
if obj.ntpRunning {
go obj.syncNtpTime()
logger.Debug("Ntp is running")
return true
}
obj.ntpRunning = true
go obj.syncNtpThread()
} else {
if obj.ntpRunning {
logger.Debug("Ntp will quit....")
obj.quitChan <- true
}
obj.ntpRunning = false
func getDateTime() (string, string, error) {
t, err := getNetworkTime()
if err != nil {
return "", "", err
}
return true
dStr := fmt.Sprintf("%d-%d-%d", t.Year(), t.Month(), t.Day())
tStr := fmt.Sprintf("%d:%d:%d", t.Hour(), t.Minute(), t.Second())
return dStr, tStr, nil
}
func getDateTimeAny(t *time.Time) (dStr, tStr string) {
dStr += strconv.FormatInt(int64(t.Year()), 10) + "-" + strconv.FormatInt(int64(t.Month()), 10) + "-" + strconv.FormatInt(int64(t.Day()), 10)
tStr += strconv.FormatInt(int64(t.Hour()), 10) + ":" + strconv.FormatInt(int64(t.Minute()), 10) + ":" + strconv.FormatInt(int64(t.Second()), 10)
return dStr, tStr
}
func getNtpTime(locale string) (*time.Time, error) {
if len(locale) < 1 {
locale = "UTC"
func getNetworkTime() (*time.Time, error) {
loc, err := time.LoadLocation(Timezone)
if err != nil {
return nil, err
}
time.Local = loc
if !timezoneIsValid(locale) {
logger.Warningf("'%s': invalid locale", locale)
locale = "UTC"
}
logger.Info("Locale:", locale)
raddr, err := net.ResolveUDPAddr("udp", _NTP_HOST+":123")
raddr, err := net.ResolveUDPAddr("udp", ntpHost+":123")
if err != nil {
return nil, err
}
@ -135,12 +157,7 @@ func getNtpTime(locale string) (*time.Time, error) {
nsec := sec * 1e9
nsec += (frac * 1e9) >> 32
l := time.FixedZone(locale, 0)
if l == nil {
return nil, err
}
t := time.Date(1900, 1, 1, 0, 0, 0, 0, l).Add(time.Duration(nsec)).Local()
t := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(nsec)).Local()
return &t, nil
}

View File

@ -19,28 +19,27 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
package ntp
import (
"os/user"
C "launchpad.net/gocheck"
"testing"
)
func getHomeDir() (string, bool) {
info, err := user.Current()
type testWrapper struct{}
func init() {
C.Suite(&testWrapper{})
}
func Test(t *testing.T) {
C.TestingT(t)
}
func (*testWrapper) TestGetDateTime(c *C.C) {
_, _, err := getDateTime()
//c.Check(err, C.Not(C.NotNil))
if err != nil {
logger.Error("Get current user info failed:", err)
return "", false
c.Skip(err.Error())
}
return info.HomeDir, true
}
func isElementExistString(ele string, list []string) bool {
for _, v := range list {
if v == ele {
return true
}
}
return false
}

View File

@ -1,291 +0,0 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
import (
"dbus/org/freedesktop/notifications"
"io/ioutil"
"os"
"path"
"pkg.linuxdeepin.com/lib/dbus"
. "pkg.linuxdeepin.com/lib/gettext"
"pkg.linuxdeepin.com/lib/glib-2.0"
dutils "pkg.linuxdeepin.com/lib/utils"
"strings"
)
type localeInfo struct {
Locale string
Desc string
}
const (
DMRC_FILE = ".dmrc"
DMRC_KEY_GROUP = "Desktop"
PAM_ENV_FILE = ".pam_environment"
DEFAULT_LOCALE_FILE = "/etc/default/locale"
)
func (obj *Manager) listenLocaleChange() {
setDate.ConnectGenLocaleStatus(func(ok bool, locale string) {
if ok && changeLocaleFlag {
//setLocaleDmrc(locale)
setLocalePamEnv(locale)
changeLocaleFlag = false
}
obj.setPropName("CurrentLocale")
dbus.Emit(obj, "LocaleStatus", ok, locale)
if ok {
sendNotify("", "", Tr("Language has been changed successfully and will be effective after logged out."))
} else {
sendNotify("", "", Tr("Language failed to change, please try later."))
}
})
}
func setLocaleDmrc(locale string) {
homeDir, ok := getHomeDir()
if !ok {
return
}
filePath := path.Join(homeDir, DMRC_FILE)
dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
"LANG", locale)
dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
"LANGUAGE", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_CTYPE", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_NUMERIC", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_TIME", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_COLLATE", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_MONETARY", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_MESSAGES", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_PAPER", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_NAME", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_ADDRESS", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_TELEPHONE", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_MEASUREMENT", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_IDENTIFICATION", locale)
//dutils.WriteKeyToKeyFile(filePath, DMRC_KEY_GROUP,
//"LC_ALL", "")
}
func genPamContents(locale string) string {
contents := ""
tmp := "LANG=" + locale + "\n"
contents += tmp
tmp = "LANGUAGE=" + locale + "\n"
contents += tmp
//tmp = "LC_CTYPE=" + locale + "\n"
//contents += tmp
//tmp = "LC_NUMERIC=" + locale + "\n"
//contents += tmp
//tmp = "LC_TIME=" + locale + "\n"
//contents += tmp
//tmp = "LC_COLLATE=" + locale + "\n"
//contents += tmp
//tmp = "LC_MONETARY=" + locale + "\n"
//contents += tmp
//tmp = "LC_MESSAGES=" + locale + "\n"
//contents += tmp
//tmp = "LC_PAPER=" + locale + "\n"
//contents += tmp
//tmp = "LC_NAME=" + locale + "\n"
//contents += tmp
//tmp = "LC_ADDRESS=" + locale + "\n"
//contents += tmp
//tmp = "LC_TELEPHONE=" + locale + "\n"
//contents += tmp
//tmp = "LC_MEASUREMENT=" + locale + "\n"
//contents += tmp
//tmp = "LC_IDENTIFICATION=" + locale + "\n"
//contents += tmp
//tmp = "LC_ALL=\n"
//contents += tmp
return contents
}
func setLocalePamEnv(locale string) {
homeDir, ok := getHomeDir()
if !ok {
return
}
filePath := path.Join(homeDir, PAM_ENV_FILE)
fp, err := os.Create(filePath + "~")
if err != nil {
logger.Errorf("Create '%s' failed: %v", filePath+"~", err)
return
}
defer fp.Close()
if _, err = fp.WriteString(genPamContents(locale)); err != nil {
logger.Errorf("Write '%s' failed: %v", filePath+"~", err)
return
}
fp.Sync()
os.Rename(filePath+"~", filePath)
}
func getDefaultLocale() (string, bool) {
if !dutils.IsFileExist(DEFAULT_LOCALE_FILE) {
logger.Errorf("'%s' not exist", DEFAULT_LOCALE_FILE)
return "", false
}
contents, err := ioutil.ReadFile(DEFAULT_LOCALE_FILE)
if err != nil {
logger.Errorf("ReadFile '%s' failed: %v", DEFAULT_LOCALE_FILE, err)
return "", false
}
retStr := ""
retOk := false
lines := strings.Split(string(contents), "\n")
for _, line := range lines {
strs := strings.Split(line, "=")
if len(strs) != 2 {
continue
}
if strs[0] != "LANG" {
continue
}
retStr = strings.Trim(strs[1], "\"")
retOk = true
break
}
return retStr, retOk
}
func getUserLocale() (string, bool) {
homeDir := dutils.GetHomeDir()
filePath := path.Join(homeDir, PAM_ENV_FILE)
if !dutils.IsFileExist(filePath) {
logger.Warningf("'%s' not exist", filePath)
return "", false
}
contents, err := ioutil.ReadFile(filePath)
if err != nil {
logger.Errorf("ReadFile '%s' failed: %v", filePath, err)
return "", false
}
retStr := ""
retOk := false
lines := strings.Split(string(contents), "\n")
for _, line := range lines {
strs := strings.Split(line, "=")
if len(strs) != 2 {
continue
}
if strs[0] != "LANG" {
continue
}
retStr = strs[1]
retOk = true
break
}
return retStr, retOk
}
func sendNotify(icon, summary, body string) {
notifier, err := notifications.NewNotifier("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
if err != nil {
logger.Error("New Notifier Failed:", err)
return
}
notifier.Notify(_DATE_TIME_DEST, 0, icon, summary, body, nil, nil, 0)
}
func getLocaleInfo(keyFile *glib.KeyFile, l, locale string) (localeInfo, bool) {
if keyFile == nil {
return localeInfo{}, false
}
lang := os.Getenv("LANG")
if len(lang) < 1 {
lang = "en_GB"
} else {
strs := strings.Split(lang, ".")
if dutils.IsElementInList(strs[0], localeList) {
lang = strs[0]
} else {
tmps := strings.Split(strs[0], "_")
if dutils.IsElementInList(tmps[0], localeList) {
lang = tmps[0]
} else {
lang = "en_GB"
}
}
}
info := localeInfo{}
v, err := keyFile.GetLocaleString(l, "Name", lang)
if err != nil {
return info, false
}
info.Locale = locale
info.Desc = v
return info, true
}
func getLocaleInfoList() (list []localeInfo) {
keyFile := glib.NewKeyFile()
defer keyFile.Free()
if _, err := keyFile.LoadFromFile("/usr/share/dde-daemon/lang/all_languages",
glib.KeyFileFlagsKeepTranslations); err != nil {
return list
}
for n, v := range localeListMap {
info, ok := getLocaleInfo(keyFile, n, v)
if !ok {
continue
}
list = append(list, info)
}
return
}

1
datetime/testdata/timezone vendored Normal file
View File

@ -0,0 +1 @@
Asia/Shanghai

View File

@ -0,0 +1,326 @@
package timezone
import (
. "pkg.linuxdeepin.com/lib/gettext"
)
type zoneDesc struct {
zone string
desc string
}
// if zoneWhiteList changed, please update dst_data
var zoneWhiteList = []zoneDesc{
zoneDesc{
zone: "Pacific/Niue",
desc: Tr("Niue"),
},
zoneDesc{
zone: "US/Hawaii",
desc: Tr("Hawaii"),
},
zoneDesc{
zone: "Pacific/Tahiti",
desc: Tr("Tahiti"),
},
zoneDesc{
zone: "Pacific/Honolulu",
desc: Tr("Honolulu"),
},
zoneDesc{
zone: "Pacific/Marquesas",
desc: Tr("Marquesas"),
},
zoneDesc{
zone: "US/Alaska",
desc: Tr("Alaska"),
},
zoneDesc{
zone: "America/Juneau",
desc: Tr("Juneau"),
},
zoneDesc{
zone: "Pacific/Gambier",
desc: Tr("Gambier"),
},
zoneDesc{
zone: "Mexico/BajaNorte",
desc: Tr("BajaNorte"),
},
zoneDesc{
zone: "America/Vancouver",
desc: Tr("Vancouver"),
},
zoneDesc{
zone: "America/Chihuahua",
desc: Tr("Chihuahua"),
},
zoneDesc{
zone: "US/Arizona",
desc: Tr("Arizona"),
},
zoneDesc{
zone: "Mexico/BajaSur",
desc: Tr("BajaSur"),
},
zoneDesc{
zone: "America/Mexico_City",
desc: Tr("Mexico City"),
},
zoneDesc{
zone: "America/Chicago",
desc: Tr("Chicago"),
},
zoneDesc{
zone: "America/Managua",
desc: Tr("Managua"),
},
zoneDesc{
zone: "America/Monterrey",
desc: Tr("Monterrey"),
},
zoneDesc{
zone: "America/New_York",
desc: Tr("New York"),
},
zoneDesc{
zone: "America/Lima",
desc: Tr("Lima"),
},
zoneDesc{
zone: "America/Bogota",
desc: Tr("Bogota"),
},
zoneDesc{
zone: "America/Caracas",
desc: Tr("Caracas"),
},
zoneDesc{
zone: "America/Cuiaba",
desc: Tr("Cuiaba"),
},
zoneDesc{
zone: "America/Santiago",
desc: Tr("Santiago"),
},
zoneDesc{
zone: "America/La_Paz",
desc: Tr("La Paz"),
},
zoneDesc{
zone: "America/Asuncion",
desc: Tr("Asuncion"),
},
zoneDesc{
zone: "Canada/Newfoundland",
desc: Tr("Newfoundland"),
},
zoneDesc{
zone: "America/Buenos_Aires",
desc: Tr("Buenos Aires"),
},
zoneDesc{
zone: "America/Cayenne",
desc: Tr("Cayenne"),
},
zoneDesc{
zone: "Brazil/DeNoronha",
desc: Tr("DeNoronha"),
},
zoneDesc{
zone: "Atlantic/Azores",
desc: Tr("Azores"),
},
zoneDesc{
zone: "Europe/London",
desc: Tr("London"),
},
zoneDesc{
zone: "Europe/Dublin",
desc: Tr("Dublin"),
},
zoneDesc{
zone: "Africa/Casablanca",
desc: Tr("Casablanca"),
},
zoneDesc{
zone: "Africa/Monrovia",
desc: Tr("Monrovia"),
},
zoneDesc{
zone: "Atlantic/Madeira",
desc: Tr("Madeira"),
},
zoneDesc{
zone: "Europe/Paris",
desc: Tr("Paris"),
},
zoneDesc{
zone: "Europe/Berlin",
desc: Tr("Berlin"),
},
zoneDesc{
zone: "Europe/Rome",
desc: Tr("Rome"),
},
zoneDesc{
zone: "Europe/Vienna",
desc: Tr("Vienna"),
},
zoneDesc{
zone: "Africa/Cairo",
desc: Tr("Cairo"),
},
zoneDesc{
zone: "Europe/Athens",
desc: Tr("Athens"),
},
zoneDesc{
zone: "Europe/Bucharest",
desc: Tr("Bucharest"),
},
zoneDesc{
zone: "Europe/Istanbul",
desc: Tr("Istanbul"),
},
zoneDesc{
zone: "Europe/Moscow",
desc: Tr("Moscow"),
},
zoneDesc{
zone: "Africa/Nairobi",
desc: Tr("Nairobi"),
},
zoneDesc{
zone: "Asia/Tehran",
desc: Tr("Tehran"),
},
zoneDesc{
zone: "Asia/Muscat",
desc: Tr("Muscat"),
},
zoneDesc{
zone: "Asia/Baku",
desc: Tr("Baku"),
},
zoneDesc{
zone: "Asia/Kabul",
desc: Tr("Kabul"),
},
zoneDesc{
zone: "Asia/Yekaterinburg",
desc: Tr("Yekaterinburg"),
},
zoneDesc{
zone: "Asia/Karachi",
desc: Tr("Karachi"),
},
zoneDesc{
zone: "Asia/Calcutta",
desc: Tr("Calcutta"),
},
zoneDesc{
zone: "Asia/Kathmandu",
desc: Tr("Kathmandu"),
},
zoneDesc{
zone: "Asia/Dhaka",
desc: Tr("Dhaka"),
},
zoneDesc{
zone: "Asia/Rangoon",
desc: Tr("Rangoon"),
},
zoneDesc{
zone: "Asia/Bangkok",
desc: Tr("Bangkok"),
},
zoneDesc{
zone: "Asia/Jakarta",
desc: Tr("Jakarta"),
},
zoneDesc{
zone: "Asia/Beijing",
desc: Tr("Beijing"),
},
zoneDesc{
zone: "Asia/Hong_Kong",
desc: Tr("Hong Kong"),
},
zoneDesc{
zone: "Asia/Taipei",
desc: Tr("Taipei"),
},
zoneDesc{
zone: "Asia/Kuala_Lumpur",
desc: Tr("Kuala Lumpur"),
},
zoneDesc{
zone: "Australia/Perth",
desc: Tr("Perth"),
},
zoneDesc{
zone: "Australia/Eucla",
desc: Tr("Eucla"),
},
zoneDesc{
zone: "Asia/Tokyo",
desc: Tr("Tokyo"),
},
zoneDesc{
zone: "Asia/Seoul",
desc: Tr("Seoul"),
},
zoneDesc{
zone: "Asia/Anadyr",
desc: Tr("Anadyr"),
},
zoneDesc{
zone: "Australia/Darwin",
desc: Tr("Darwin"),
},
zoneDesc{
zone: "Australia/Sydney",
desc: Tr("Sydney"),
},
zoneDesc{
zone: "Pacific/Guam",
desc: Tr("Guam"),
},
zoneDesc{
zone: "Australia/Melbourne",
desc: Tr("Melbourne"),
},
zoneDesc{
zone: "Australia/Hobart",
desc: Tr("Hobart"),
},
zoneDesc{
zone: "Australia/Lord_Howe",
desc: Tr("Lord Howe"),
},
zoneDesc{
zone: "Pacific/Pohnpei",
desc: Tr("Pohnpei"),
},
zoneDesc{
zone: "Pacific/Norfolk",
desc: Tr("Norfolk"),
},
zoneDesc{
zone: "Pacific/Auckland",
desc: Tr("Auckland"),
},
zoneDesc{
zone: "Pacific/Chatham",
desc: Tr("Chatham"),
},
zoneDesc{
zone: "Pacific/Apia",
desc: Tr("Apia"),
},
zoneDesc{
zone: "Pacific/Fakaofo",
desc: Tr("Fakaofo"),
},
}

View File

@ -0,0 +1,87 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package timezone
import (
"fmt"
"io/ioutil"
"strconv"
"strings"
)
type dstData struct {
zone string
dst DSTInfo
}
var errNoDST = fmt.Errorf("The zone has not dst info")
const dstDataFile = "/usr/share/dde-daemon/dst_data"
func parseDSTDataFile(filename string) ([]dstData, error) {
contents, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
lines := strings.Split(string(contents), "\n")
var infos []dstData
for _, line := range lines {
if len(line) == 0 {
continue
}
strs := strings.Split(line, ";")
if len(strs) != 4 {
continue
}
enter, _ := strconv.ParseInt(strs[1], 10, 64)
leave, _ := strconv.ParseInt(strs[2], 10, 64)
offset, _ := strconv.ParseInt(strs[3], 10, 64)
info := dstData{
zone: strs[0],
dst: DSTInfo{
Enter: enter,
Leave: leave,
DSTOffset: int32(offset),
},
}
infos = append(infos, info)
}
return infos, nil
}
func findDSTInfo(zone, filename string) (*DSTInfo, error) {
infos, err := parseDSTDataFile(filename)
if err != nil {
return nil, err
}
for _, info := range infos {
if info.zone == zone {
return &info.dst, nil
}
}
return nil, errNoDST
}

36
datetime/timezone/testdata/dst_data vendored Normal file
View File

@ -0,0 +1,36 @@
US/Alaska;1394362800;1414922400;-28800
America/Juneau;1394362800;1414922400;-28800
Mexico/BajaNorte;1394359200;1414918800;-25200
America/Vancouver;1394359200;1414918800;-25200
America/Chihuahua;1396774800;1414310400;-21600
Mexico/BajaSur;1396774800;1414310400;-21600
America/Mexico_City;1396771200;1414306800;-18000
America/Chicago;1394352000;1414911600;-18000
America/Monterrey;1396771200;1414306800;-18000
America/New_York;1394348400;1414908000;-14400
America/Cuiaba;1392519600;1413691200;-14400
America/Santiago;1398567600;1410062400;-14400
America/Asuncion;1395543600;1412481600;-14400
Canada/Newfoundland;1394343000;1414902600;-9000
Atlantic/Azores;1396141200;1414285200;0
Europe/London;1396141200;1414285200;3600
Europe/Dublin;1396141200;1414285200;3600
Africa/Casablanca;1396144800;1403920800;3600
Atlantic/Madeira;1396141200;1414285200;3600
Europe/Paris;1396141200;1414285200;7200
Europe/Berlin;1396141200;1414285200;7200
Europe/Rome;1396141200;1414285200;7200
Europe/Vienna;1396141200;1414285200;7200
Africa/Cairo;1400191200;1403816400;10800
Europe/Athens;1396141200;1414285200;10800
Europe/Bucharest;1396141200;1414285200;10800
Europe/Istanbul;1396227600;1414285200;10800
Asia/Tehran;1395433800;1411327800;16200
Asia/Baku;1396137600;1414281600;18000
Australia/Sydney;1396713600;1412438400;36000
Australia/Melbourne;1396713600;1412438400;36000
Australia/Hobart;1396713600;1412438400;36000
Australia/Lord_Howe;1396710000;1412436600;37800
Pacific/Auckland;1396706400;1411826400;43200
Pacific/Chatham;1396706400;1411826400;45900
Pacific/Apia;1396706400;1411826400;46800

View File

@ -0,0 +1,360 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
#include <stdio.h> /* for stdout, stderr, perror */
#include <string.h> /* for strcpy */
#include <sys/types.h> /* for time_t */
#include <time.h> /* for struct tm */
#include <stdlib.h> /* for exit, malloc, atoi */
#include <limits.h> /* for CHAR_BIT, LLONG_MAX */
#include <ctype.h> /* for isalpha et al. */
#include "timestamp.h"
#ifndef INT_FAST32_MAX
# if INT_MAX >> 31 == 0
typedef long int_fast32_t;
# else
typedef int int_fast32_t;
# endif
#endif
#ifndef INTMAX_MAX
# if defined LLONG_MAX || defined __LONG_LONG_MAX__
typedef long long intmax_t;
# ifdef LLONG_MAX
# define INTMAX_MAX LLONG_MAX
# else
# define INTMAX_MAX __LONG_LONG_MAX__
# endif
# else
typedef long intmax_t;
# define INTMAX_MAX LONG_MAX
# endif
#endif
#ifndef ZDUMP_LO_YEAR
#define ZDUMP_LO_YEAR (-500)
#endif /* !defined ZDUMP_LO_YEAR */
#ifndef ZDUMP_HI_YEAR
#define ZDUMP_HI_YEAR 2500
#endif /* !defined ZDUMP_HI_YEAR */
#ifndef MAX_STRING_LENGTH
#define MAX_STRING_LENGTH 1024
#endif /* !defined MAX_STRING_LENGTH */
#ifndef SECSPERMIN
#define SECSPERMIN 60
#endif /* !defined SECSPERMIN */
#ifndef MINSPERHOUR
#define MINSPERHOUR 60
#endif /* !defined MINSPERHOUR */
#ifndef SECSPERHOUR
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#endif /* !defined SECSPERHOUR */
#ifndef HOURSPERDAY
#define HOURSPERDAY 24
#endif /* !defined HOURSPERDAY */
#ifndef EPOCH_YEAR
#define EPOCH_YEAR 1970
#endif /* !defined EPOCH_YEAR */
#ifndef TM_YEAR_BASE
#define TM_YEAR_BASE 1900
#endif /* !defined TM_YEAR_BASE */
#ifndef DAYSPERNYEAR
#define DAYSPERNYEAR 365
#endif /* !defined DAYSPERNYEAR */
#ifndef isleap
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#endif /* !defined isleap */
#ifndef isleap_sum
/*
** See tzfile.h for details on isleap_sum.
*/
#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
#endif /* !defined isleap_sum */
#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
#define SECSPER400YEARS (SECSPERNYEAR * (intmax_t) (300 + 3) \
+ SECSPERLYEAR * (intmax_t) (100 - 3))
/*
** True if SECSPER400YEARS is known to be representable as an
** intmax_t. It's OK that SECSPER400YEARS_FITS can in theory be false
** even if SECSPER400YEARS is representable, because when that happens
** the code merely runs a bit more slowly, and this slowness doesn't
** occur on any practical platform.
*/
enum { SECSPER400YEARS_FITS = SECSPERLYEAR <= INTMAX_MAX / 400 };
extern char * tzname[2];
/* The minimum and maximum finite time values. */
static time_t const absolute_min_time =
((time_t) -1 < 0
? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
: 0);
static time_t const absolute_max_time =
((time_t) -1 < 0
? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
: -1);
static char * abbr(struct tm * tmp);
static intmax_t delta(struct tm * newp, struct tm * oldp);
static time_t hunt(time_t lot, time_t hit);
static time_t yeartot(intmax_t y);
long long*
get_dst_time(const char *zone, int year)
{
register time_t cutlotime;
register time_t cuthitime;
cutlotime = yeartot(year);
cuthitime = yeartot(year+1);
time_t t;
time_t newt;
struct tm tm;
struct tm newtm;
register struct tm * tmp;
register struct tm * newtmp;
static char buf[MAX_STRING_LENGTH];
if (setenv("TZ", zone, 1) != 0 ) {
printf("Set TZ=%s failed\n", zone);
return NULL;
}
t = absolute_min_time;
if (t < cutlotime)
t = cutlotime;
tmp = localtime(&t);
if (tmp != NULL) {
tm = *tmp;
strncpy(buf, abbr(&tm), (sizeof buf) - 1);
}
long long *ret = calloc(3, sizeof(long long));
if (!ret) {
return NULL;
}
ret[2] = 0;
int idx = 0;
for ( ; ; ) {
newt = (t < absolute_max_time - SECSPERDAY / 2
? t + SECSPERDAY / 2
: absolute_max_time);
if (cuthitime <= newt)
break;
newtmp = localtime(&newt);
if (newtmp != NULL)
newtm = *newtmp;
if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
(delta(&newtm, &tm) != (newt - t) ||
newtm.tm_isdst != tm.tm_isdst ||
strcmp(abbr(&newtm), buf) != 0)) {
newt = hunt(t, newt);
if (idx < 2) {
ret[idx++] = newt;
ret[2]++;
}
newtmp = localtime(&newt);
if (newtmp != NULL) {
newtm = *newtmp;
strncpy(buf,
abbr(&newtm),
(sizeof buf) - 1);
}
}
t = newt;
tm = newtm;
tmp = newtmp;
}
return ret;
}
long long
get_year_begin_time(const char *zone, int year)
{
// TODO: check return val
setenv("TZ", zone, 1);
struct tm tm;
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
tm.tm_mday = 1;
tm.tm_mon = 1;
tm.tm_year = year - TM_YEAR_BASE;
return mktime(&tm);
}
long
getoffset (const char *zone, long long t)
{
struct tm *tp = localtime((time_t*)&t);
if (!tp) {
return -1;
}
# if defined __USE_MISC
return tp->tm_gmtoff;
# else
return tp->__tm_gmtoff;
#endif
}
static time_t
yeartot(const intmax_t y)
{
register intmax_t myy, seconds, years;
register time_t t;
myy = EPOCH_YEAR;
t = 0;
while (myy < y) {
if (SECSPER400YEARS_FITS && 400 <= y - myy) {
intmax_t diff400 = (y - myy) / 400;
if (INTMAX_MAX / SECSPER400YEARS < diff400)
return absolute_max_time;
seconds = diff400 * SECSPER400YEARS;
years = diff400 * 400;
} else {
seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
years = 1;
}
myy += years;
if (t > absolute_max_time - seconds)
return absolute_max_time;
t += seconds;
}
while (y < myy) {
if (SECSPER400YEARS_FITS && y + 400 <= myy && myy < 0) {
intmax_t diff400 = (myy - y) / 400;
if (INTMAX_MAX / SECSPER400YEARS < diff400)
return absolute_min_time;
seconds = diff400 * SECSPER400YEARS;
years = diff400 * 400;
} else {
seconds = isleap(myy - 1) ? SECSPERLYEAR : SECSPERNYEAR;
years = 1;
}
myy -= years;
if (t < absolute_min_time + seconds)
return absolute_min_time;
t -= seconds;
}
return t;
}
static time_t
hunt(time_t lot, time_t hit)
{
time_t t;
struct tm lotm;
register struct tm * lotmp;
struct tm tm;
register struct tm * tmp;
char loab[MAX_STRING_LENGTH];
lotmp = localtime(&lot);
if (lotmp != NULL) {
lotm = *lotmp;
strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
}
for ( ; ; ) {
time_t diff = hit - lot;
if (diff < 2)
break;
t = lot;
t += diff / 2;
if (t <= lot)
++t;
else if (t >= hit)
--t;
tmp = localtime(&t);
if (tmp != NULL)
tm = *tmp;
if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
(delta(&tm, &lotm) == (t - lot) &&
tm.tm_isdst == lotm.tm_isdst &&
strcmp(abbr(&tm), loab) == 0)) {
lot = t;
lotm = tm;
lotmp = tmp;
} else hit = t;
}
return hit;
}
/*
** Thanks to Paul Eggert for logic used in delta.
*/
static intmax_t
delta(struct tm * newp, struct tm *oldp)
{
register intmax_t result;
register int tmy;
if (newp->tm_year < oldp->tm_year)
return -delta(oldp, newp);
result = 0;
for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
result += newp->tm_yday - oldp->tm_yday;
result *= HOURSPERDAY;
result += newp->tm_hour - oldp->tm_hour;
result *= MINSPERHOUR;
result += newp->tm_min - oldp->tm_min;
result *= SECSPERMIN;
result += newp->tm_sec - oldp->tm_sec;
return result;
}
static char *
abbr(struct tm *tmp)
{
register char * result;
static char nada;
if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
return &nada;
result = tzname[tmp->tm_isdst];
return (result == NULL) ? &nada : result;
}

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
#ifndef __TIMESTAMP_H__
#define __TIMESTAMP_H__
long long get_year_begin_time(const char *zone, int year);
long getoffset (const char *zone, long long t);
long long * get_dst_time(const char *zone, int year);
#endif

View File

@ -0,0 +1,104 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package timezone
// #cgo CFLAGS: -Wall -g
// #include <stdlib.h>
// #include "timestamp.h"
import "C"
import (
"time"
"unsafe"
)
func sumDSTTime(zone string, year int32) (int64, int64, bool) {
czone := C.CString(zone)
ret := C.get_dst_time(czone, C.int(year))
tmp := uintptr(unsafe.Pointer(ret))
l := unsafe.Sizeof(*ret)
first := int64(*ret)
second := int64(*(*C.longlong)(unsafe.Pointer(tmp + uintptr(l))))
third := int64(*(*C.longlong)(unsafe.Pointer(tmp + uintptr(l)*2)))
C.free(unsafe.Pointer(czone))
C.free(unsafe.Pointer(ret))
if third != 2 {
return 0, 0, false
}
return first, second, true
}
func getOffsetByTimestamp(zone string, timestamp int64) int32 {
czone := C.CString(zone)
off := C.getoffset(czone, C.longlong(timestamp))
C.free(unsafe.Pointer(czone))
return int32(off)
}
func getYearBeginTime(zone string, year int32) int64 {
czone := C.CString(zone)
timestamp := C.get_year_begin_time(czone, C.int(year))
C.free(unsafe.Pointer(czone))
return int64(timestamp)
}
func newDSTInfo(zone string) *DSTInfo {
dst, err := findDSTInfo(zone, dstDataFile)
if err == errNoDST || err == nil {
return dst
}
year := time.Now().Year()
first, second, ok := sumDSTTime(zone, int32(year))
if !ok {
return nil
}
off := getOffsetByTimestamp(zone, first)
return &DSTInfo{
Enter: first,
Leave: second,
DSTOffset: off,
}
}
func newZoneSummary(zone string) *ZoneSummary {
var info ZoneSummary
year := time.Now().Year()
info.Name = zone
info.Desc = getZoneDesc(zone)
//info.DST = newDSTInfo(zone, year)
off := getOffsetByTimestamp(zone,
getYearBeginTime(zone, int32(year)))
info.RawOffset = off
return &info
}

133
datetime/timezone/zone.go Normal file
View File

@ -0,0 +1,133 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package timezone
import (
"dbus/com/deepin/api/setdatetime"
"fmt"
"path"
dutils "pkg.linuxdeepin.com/lib/utils"
)
type DSTInfo struct {
Enter int64
Leave int64
DSTOffset int32
}
type ZoneSummary struct {
Name string
Desc string
RawOffset int32
}
type ZoneInfo struct {
Summary ZoneSummary
DST DSTInfo
}
var (
ErrInvalidZone = fmt.Errorf("Invalid Timezone")
)
const (
zoneInfoDir = "/usr/share/zoneinfo"
zoneInfoFile = "/usr/share/dde-daemon/zone_info.json"
zoneDSTFile = "/usr/share/dde-daemon/zone_dst"
)
func IsZoneValid(zone string) bool {
if len(zone) == 0 {
return false
}
filename := path.Join(zoneInfoDir, zone)
if dutils.IsFileExist(filename) {
return true
}
return false
}
func SetTimezone(zone string) error {
if !IsZoneValid(zone) {
return ErrInvalidZone
}
datetime, err := setdatetime.NewSetDateTime(
"com.deepin.api.SetDateTime",
"/com/deepin/api/SetDateTime")
if err != nil {
return err
}
_, err = datetime.SetTimezone(zone)
if err != nil {
return err
}
setdatetime.DestroySetDateTime(datetime)
return nil
}
var _infos []ZoneSummary
func GetZoneSummaryList() []ZoneSummary {
if _infos != nil {
return _infos
}
for _, tmp := range zoneWhiteList {
summary := newZoneSummary(tmp.zone)
_infos = append(_infos, *summary)
}
return _infos
}
func GetZoneInfo(zone string) (*ZoneInfo, error) {
if !IsZoneValid(zone) {
return nil, ErrInvalidZone
}
var info ZoneInfo
summary := newZoneSummary(zone)
info.Summary = *summary
dst := newDSTInfo(zone)
if dst != nil {
info.DST = *dst
}
return &info, nil
}
func getZoneDesc(zone string) string {
for _, tmp := range zoneWhiteList {
if zone == tmp.zone {
return tmp.desc
}
}
return zone
}

View File

@ -0,0 +1,200 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package timezone
import (
C "launchpad.net/gocheck"
"os"
"testing"
)
type testWrapper struct{}
func Test(t *testing.T) {
C.TestingT(t)
}
func init() {
C.Suite(&testWrapper{})
}
func (*testWrapper) TestGetZoneList(c *C.C) {
zoneList := GetZoneSummaryList()
c.Check(len(zoneList), C.Equals, len(zoneWhiteList))
}
type testZoneSummary struct {
zone string
dstOffset string
ret bool
}
var infos = []testZoneSummary{
{
zone: "America/Atka",
dstOffset: "09:00",
ret: true,
},
{
zone: "US/Aleutian",
dstOffset: "09:00",
ret: true,
},
{
zone: "Pacific/Niue",
dstOffset: "",
ret: true,
},
{
zone: "Pacific/Niueiii",
dstOffset: "",
ret: false,
},
}
func (*testWrapper) TestZoneValid(c *C.C) {
for _, info := range infos {
c.Check(IsZoneValid(info.zone), C.Equals, info.ret)
}
}
func (*testWrapper) TestNewDSTInfo(c *C.C) {
type testDST struct {
zone string
dst DSTInfo
}
var infos = []testDST{
{
zone: "Asia/Shanghai",
dst: DSTInfo{
Enter: 0,
Leave: 0,
DSTOffset: 0,
},
},
{
zone: "America/New_York",
dst: DSTInfo{
Enter: 1394348400,
Leave: 1414908000,
DSTOffset: -14400,
},
},
}
for _, info := range infos {
e, l, ok := sumDSTTime(info.zone, 2014)
c.Check(e, C.Equals, info.dst.Enter)
c.Check(l, C.Equals, info.dst.Leave)
if !ok {
continue
}
off := getOffsetByTimestamp(info.zone, e)
c.Check(off, C.Equals, info.dst.DSTOffset)
}
}
func (*testWrapper) TestZoneDesc(c *C.C) {
var infos = []zoneDesc{
{
zone: "Asia/Beijing",
desc: "Beijing",
},
{
zone: "Pacific/Johnston",
desc: "Pacific/Johnston",
},
}
lang := os.Getenv("LANG")
os.Setenv("LANG", "en_US.UTF-8")
for _, info := range infos {
c.Check(getZoneDesc(info.zone), C.Equals, info.desc)
}
os.Setenv("LANG", lang)
}
func (*testWrapper) TestFindDSTInfo(c *C.C) {
type testDSTData struct {
data dstData
ret bool
}
// dst info for 2014
var infos = []testDSTData{
{
data: dstData{
zone: "US/Alaska",
dst: DSTInfo{
Enter: 1394362800,
Leave: 1414922400,
DSTOffset: -28800,
},
},
ret: true,
},
{
data: dstData{
zone: "Atlantic/Azores",
dst: DSTInfo{
Enter: 1396141200,
Leave: 1414285200,
DSTOffset: 0,
},
},
ret: true,
},
{
data: dstData{
zone: "Pacific/Apia",
dst: DSTInfo{
Enter: 1396706400,
Leave: 1411826400,
DSTOffset: 46800,
},
},
ret: true,
},
{
data: dstData{
zone: "Asia/Shanghai",
dst: DSTInfo{},
},
ret: false,
},
}
for _, info := range infos {
dst, err := findDSTInfo(info.data.zone, "testdata/dst_data")
if info.ret {
c.Check(err, C.IsNil)
c.Check(info.data.dst.Enter, C.Equals, dst.Enter)
c.Check(info.data.dst.Leave, C.Equals, dst.Leave)
c.Check(info.data.dst.DSTOffset, C.Equals, dst.DSTOffset)
} else {
c.Check(dst, C.IsNil)
c.Check(err, C.NotNil)
}
}
}

View File

@ -1,114 +0,0 @@
/**
* Copyright (c) 2011 ~ 2013 Deepin, Inc.
* 2011 ~ 2013 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package datetime
func checkLocaleValid(locale string) bool {
for _, v := range localeListMap {
if v == locale {
return true
}
}
return false
}
func timezoneIsValid(tz string) bool {
for _, info := range zoneInfos {
if tz == info.Zone {
return true
}
}
return false
}
func convertZoneToCity(tz string) string {
city := ""
for _, c := range tz {
if c == '-' || c == '_' {
city = city + " "
} else {
city = city + string(c)
}
}
return city
}
func convertCityToZone(city string) string {
tz := ""
if isInUnderlineList(city) {
for _, c := range city {
if c == ' ' {
tz = tz + "_"
} else {
tz = tz + string(c)
}
}
} else {
for _, c := range city {
if c == ' ' {
tz = tz + "-"
} else {
tz = tz + string(c)
}
}
}
return tz
}
func isInUnderlineList(key string) bool {
ok := isElementExist(key, noUnderlineList)
if ok {
return false
}
return true
}
func isElementExist(element string, list []string) bool {
for _, v := range list {
if v == element {
return true
}
}
return false
}
func strArrayIsEqual(array1, array2 []string) bool {
l1 := len(array1)
l2 := len(array2)
if l1 != l2 {
return false
}
for i := 0; i < l1; i++ {
if array1[i] != array2[i] {
return false
}
}
return true
}

74
datetime/utils/print.go Normal file
View File

@ -0,0 +1,74 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package utils
import (
"pkg.linuxdeepin.com/lib/log"
)
func Printf(logger *log.Logger, format string, v ...interface{}) {
if logger == nil {
return
}
logger.Infof(format, v...)
}
func Println(logger *log.Logger, v ...interface{}) {
if logger == nil {
return
}
logger.Info(v...)
}
func Warningf(logger *log.Logger, format string, v ...interface{}) {
if logger == nil {
return
}
logger.Warningf(format, v...)
}
func Warning(logger *log.Logger, v ...interface{}) {
if logger == nil {
return
}
logger.Warning(v...)
}
func Errorf(logger *log.Logger, format string, v ...interface{}) {
if logger == nil {
return
}
logger.Errorf(format, v...)
}
func Error(logger *log.Logger, v ...interface{}) {
if logger == nil {
return
}
logger.Error(v...)
}

View File

@ -0,0 +1,85 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package utils
import (
"dbus/com/deepin/api/setdatetime"
"fmt"
)
var (
errUninitialized = fmt.Errorf("SetDateTime Uninitialized")
)
var _setDate *setdatetime.SetDateTime
func InitSetDateTime() error {
if _setDate != nil {
return nil
}
var err error
_setDate, err = setdatetime.NewSetDateTime(
"com.deepin.api.SetDateTime",
"/com/deepin/api/SetDateTime",
)
if err != nil {
return err
}
return nil
}
func DestroySetDateTime() {
if _setDate == nil {
return
}
setdatetime.DestroySetDateTime(_setDate)
_setDate = nil
}
func SetDate(value string) error {
if _setDate == nil {
return errUninitialized
}
_, err := _setDate.SetCurrentDate(value)
if err != nil {
return err
}
return nil
}
func SetTime(value string) error {
if _setDate == nil {
return errUninitialized
}
_, err := _setDate.SetCurrentTime(value)
if err != nil {
return err
}
return nil
}

105
datetime/utils/utils.go Normal file
View File

@ -0,0 +1,105 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package utils
func IsStrInList(value string, list []string) bool {
for _, s := range list {
if s == value {
return true
}
}
return false
}
func IsYearValid(value int32) bool {
if value >= 1970 {
return true
}
return false
}
func IsMonthValid(value int32) bool {
if value > 0 && value < 13 {
return true
}
return false
}
func IsDayValid(year, month, value int32) bool {
switch month {
case 1, 3, 5, 7, 8, 10, 12:
if value > 0 && value < 32 {
return true
}
case 4, 6, 9, 11:
if value > 0 && value < 31 {
return true
}
case 2:
if IsLeapYear(year) {
if value > 0 && value < 30 {
return true
}
} else {
if value > 0 && value < 29 {
return true
}
}
}
return false
}
func IsHourValid(value int32) bool {
if value >= 0 && value < 24 {
return true
}
return false
}
func IsMinuteValid(value int32) bool {
if value >= 0 && value < 60 {
return true
}
return false
}
func IsSecondValid(value int32) bool {
if value >= 0 && value < 61 {
return true
}
return false
}
func IsLeapYear(value int32) bool {
if value%400 == 0 ||
(value%4 == 0 && value%100 != 0) {
return true
}
return false
}

View File

@ -0,0 +1,300 @@
/**
* Copyright (c) 2011 ~ 2014 Deepin, Inc.
* 2013 ~ 2014 jouyouyun
*
* Author: jouyouyun <jouyouwen717@gmail.com>
* Maintainer: jouyouyun <jouyouwen717@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
**/
package utils
import (
C "launchpad.net/gocheck"
"testing"
)
type testWrapper struct{}
func init() {
C.Suite(&testWrapper{})
}
func Test(t *testing.T) {
C.TestingT(t)
}
func (*testWrapper) TestStrInList(c *C.C) {
list := []string{
"1111",
"2222",
"aaaa",
"bbbb",
}
c.Check(IsStrInList("1111", list), C.Equals, true)
c.Check(IsStrInList("aaaa", list), C.Equals, true)
c.Check(IsStrInList("xxxxxx", list), C.Equals, false)
}
type dateInfo struct {
d int32
ret bool
}
func (*testWrapper) TestYearValid(c *C.C) {
var infos = []dateInfo{
{
d: 2014,
ret: true,
},
{
d: 1970,
ret: true,
},
{
d: 1,
ret: false,
},
{
d: -2014,
ret: false,
},
}
for _, info := range infos {
c.Check(IsYearValid(info.d), C.Equals, info.ret)
}
}
func (*testWrapper) TestMonthValid(c *C.C) {
var infos = []dateInfo{
{
d: 1,
ret: true,
},
{
d: 12,
ret: true,
},
{
d: 13,
ret: false,
},
{
d: 0,
ret: false,
},
}
for _, info := range infos {
c.Check(IsMonthValid(info.d), C.Equals, info.ret)
}
}
func (*testWrapper) TestDayValid(c *C.C) {
type mdayInfo struct {
year int32
month int32
mday int32
ret bool
}
var infos = []mdayInfo{
{
year: 2014,
month: 3,
mday: 1,
ret: true,
},
{
year: 2014,
month: 3,
mday: 31,
ret: true,
},
{
year: 2014,
month: 3,
mday: 32,
ret: false,
},
{
year: 2014,
month: 3,
mday: 0,
ret: false,
},
{
year: 2014,
month: 2,
mday: 1,
ret: true,
},
{
year: 2014,
month: 2,
mday: 28,
ret: true,
},
{
year: 2014,
month: 2,
mday: 29,
ret: false,
},
{
year: 2014,
month: 2,
mday: 0,
ret: false,
},
{
year: 2014,
month: 4,
mday: 1,
ret: true,
},
{
year: 2014,
month: 4,
mday: 30,
ret: true,
},
{
year: 2014,
month: 4,
mday: 0,
ret: false,
},
{
year: 2014,
month: 4,
mday: 31,
ret: false,
},
{
year: 2000,
month: 2,
mday: 29,
ret: true,
},
}
for _, info := range infos {
c.Check(IsDayValid(info.year, info.month, info.mday),
C.Equals, info.ret)
}
}
func (*testWrapper) TestHourValid(c *C.C) {
var infos = []dateInfo{
{
d: 0,
ret: true,
},
{
d: 23,
ret: true,
},
{
d: 24,
ret: false,
},
{
d: -1,
ret: false,
},
}
for _, info := range infos {
c.Check(IsHourValid(info.d), C.Equals, info.ret)
}
}
func (*testWrapper) TestMinuteValid(c *C.C) {
var infos = []dateInfo{
{
d: 0,
ret: true,
},
{
d: 59,
ret: true,
},
{
d: 60,
ret: false,
},
{
d: -1,
ret: false,
},
}
for _, info := range infos {
c.Check(IsMinuteValid(info.d), C.Equals, info.ret)
}
}
func (*testWrapper) TestSecondValid(c *C.C) {
var infos = []dateInfo{
{
d: 0,
ret: true,
},
{
d: 60,
ret: true,
},
{
d: 61,
ret: false,
},
{
d: -1,
ret: false,
},
}
for _, info := range infos {
c.Check(IsSecondValid(info.d), C.Equals, info.ret)
}
}
func (*testWrapper) TestLeapYear(c *C.C) {
var infos = []dateInfo{
{
d: 2000,
ret: true,
},
{
d: 2004,
ret: true,
},
{
d: 2100,
ret: false,
},
{
d: 2014,
ret: false,
},
}
for _, info := range infos {
c.Check(IsLeapYear(info.d), C.Equals, info.ret)
}
}

View File

@ -1,605 +0,0 @@
package datetime
import "path"
import dutils "pkg.linuxdeepin.com/lib/utils"
import . "pkg.linuxdeepin.com/lib/gettext"
type zoneCityInfo struct {
Zone string
Desc string
}
var zoneInfos []zoneCityInfo
func checkZoneValid(offset, zone, desc string) {
if !dutils.IsFileExist(path.Join("/usr/share/zoneinfo", zone)) {
return
}
info := zoneCityInfo{zone, "UTC" + offset + " " + desc}
zoneInfos = append(zoneInfos, info)
}
func initZoneInfos() {
checkZoneValid("-11:00", "Pacific/Midway", Tr("Midway"))
checkZoneValid("-11:00", "Pacific/Niue", Tr("Niue"))
checkZoneValid("-11:00", "Pacific/Pago_Pago", Tr("Pago Pago"))
//checkZoneValid("-11:00", "Pacific/Samoa", Tr("Pacific/Samoa"))
//checkZoneValid("-11:00", "US/Samoa", Tr("US/Samoa"))
checkZoneValid("-10:00", "America/Adak", Tr("Adak"))
checkZoneValid("-10:00", "America/Atka", Tr("Atka"))
checkZoneValid("-10:00", "Pacific/Honolulu", Tr("Honolulu"))
checkZoneValid("-10:00", "Pacific/Johnston", Tr("Johnston"))
checkZoneValid("-10:00", "Pacific/Rarotonga", Tr("Rarotonga"))
checkZoneValid("-10:00", "Pacific/Tahiti", Tr("Tahiti"))
checkZoneValid("-10:00", "US/Aleutian", Tr("Aleutian"))
checkZoneValid("-10:00", "US/Hawaii", Tr("Hawaii"))
checkZoneValid("-09:30", "Pacific/Marquesas", Tr("Marquesas"))
checkZoneValid("-09:00", "America/Anchorage", Tr("Anchorage"))
checkZoneValid("-09:00", "America/Juneau", Tr("Juneau"))
checkZoneValid("-09:00", "America/Nome", Tr("Nome"))
checkZoneValid("-09:00", "America/Sitka", Tr("Sitka"))
checkZoneValid("-09:00", "America/Yakutat", Tr("Yakutat"))
checkZoneValid("-09:00", "Pacific/Gambier", Tr("Gambier"))
checkZoneValid("-09:00", "US/Alaska", Tr("Alaska"))
checkZoneValid("-08:00", "America/Dawson", Tr("Dawson"))
checkZoneValid("-08:00", "America/Ensenada", Tr("Ensenada"))
checkZoneValid("-08:00", "America/Los_Angeles", Tr("Los Angeles"))
checkZoneValid("-08:00", "America/Metlakatla", Tr("Metlakatla"))
checkZoneValid("-08:00", "America/Santa_Isabel", Tr("Santa Isabel"))
checkZoneValid("-08:00", "America/Tijuana", Tr("Tijuana"))
checkZoneValid("-08:00", "America/Vancouver", Tr("Vancouver"))
checkZoneValid("-08:00", "America/Whitehorse", Tr("Whitehorse"))
//checkZoneValid("-08:00", "Canada/Pacific", Tr("Canada/Pacific"))
checkZoneValid("-08:00", "Canada/Yukon", Tr("Yukon"))
checkZoneValid("-08:00", "Mexico/BajaNorte", Tr("BajaNorte"))
checkZoneValid("-08:00", "Pacific/Pitcairn", Tr("Pitcairn"))
//checkZoneValid("-08:00", "US/Pacific", Tr("US/Pacific"))
checkZoneValid("-07:00", "America/Boise", Tr("Boise"))
checkZoneValid("-07:00", "America/Cambridge_Bay", Tr("Cambridge Bay"))
checkZoneValid("-07:00", "America/Chihuahua", Tr("Chihuahua"))
checkZoneValid("-07:00", "America/Creston", Tr("Creston"))
checkZoneValid("-07:00", "America/Dawson_Creek", Tr("Dawson Creek"))
checkZoneValid("-07:00", "America/Denver", Tr("Denver"))
checkZoneValid("-07:00", "America/Edmonton", Tr("Edmonton"))
checkZoneValid("-07:00", "America/Hermosillo", Tr("Hermosillo"))
checkZoneValid("-07:00", "America/Inuvik", Tr("Inuvik"))
checkZoneValid("-07:00", "America/Mazatlan", Tr("Mazatlan"))
checkZoneValid("-07:00", "America/Ojinaga", Tr("Ojinaga"))
checkZoneValid("-07:00", "America/Phoenix", Tr("Phoenix"))
checkZoneValid("-07:00", "America/Shiprock", Tr("Shiprock"))
checkZoneValid("-07:00", "America/Yellowknife", Tr("Yellowknife"))
checkZoneValid("-07:00", "Canada/Mountain", Tr("Canada/Mountain"))
checkZoneValid("-07:00", "Mexico/BajaSur", Tr("BajaSur"))
checkZoneValid("-07:00", "Navajo", Tr("Navajo"))
checkZoneValid("-07:00", "US/Arizona", Tr("Arizona"))
checkZoneValid("-07:00", "US/Mountain", Tr("US/Mountain"))
checkZoneValid("-06:00", "America/Bahia_Banderas", Tr("Bahia Banderas"))
checkZoneValid("-06:00", "America/Belize", Tr("Belize"))
checkZoneValid("-06:00", "America/Cancun", Tr("Cancun"))
checkZoneValid("-06:00", "America/Chicago", Tr("Chicago"))
checkZoneValid("-06:00", "America/Costa_Rica", Tr("Costa Rica"))
checkZoneValid("-06:00", "America/El_Salvador", Tr("El Salvador"))
checkZoneValid("-06:00", "America/Guatemala", Tr("Guatemala"))
//checkZoneValid("-06:00", "America/Indiana/Knox", Tr("Indiana/Knox"))
checkZoneValid("-06:00", "America/Indiana/Tell_City", Tr("Tell City"))
checkZoneValid("-06:00", "America/Indiana/Valparaiso", Tr("Valparaiso"))
checkZoneValid("-06:00", "America/Knox_IN", Tr("Knox IN"))
checkZoneValid("-06:00", "America/Managua", Tr("Managua"))
checkZoneValid("-06:00", "America/Matamoros", Tr("Matamoros"))
checkZoneValid("-06:00", "America/Menominee", Tr("Menominee"))
checkZoneValid("-06:00", "America/Merida", Tr("Merida"))
checkZoneValid("-06:00", "America/Mexico_City", Tr("Mexico City"))
checkZoneValid("-06:00", "America/Monterrey", Tr("Monterrey"))
checkZoneValid("-06:00", "America/North_Dakota/Beulah", Tr("Beulah"))
checkZoneValid("-06:00", "America/North_Dakota/Center", Tr("North Dakota/Center"))
checkZoneValid("-06:00", "America/North_Dakota/New_Salem", Tr("North Dakota/New Salem"))
checkZoneValid("-06:00", "America/Rainy_River", Tr("Rainy River"))
checkZoneValid("-06:00", "America/Rankin_Inlet", Tr("Rankin Inlet"))
checkZoneValid("-06:00", "America/Regina", Tr("Regina"))
checkZoneValid("-06:00", "America/Resolute", Tr("Resolute"))
checkZoneValid("-06:00", "America/Swift_Current", Tr("Swift Current"))
checkZoneValid("-06:00", "America/Tegucigalpa", Tr("Tegucigalpa"))
checkZoneValid("-06:00", "America/Winnipeg", Tr("Winnipeg"))
//checkZoneValid("-06:00", "Canada/Central", Tr("Canada/Central"))
checkZoneValid("-06:00", "Canada/East-Saskatchewan", Tr("East-Saskatchewan"))
checkZoneValid("-06:00", "Canada/Saskatchewan", Tr("Saskatchewan"))
//checkZoneValid("-06:00", "Chile/EasterIsland", Tr("EasterIsland"))
checkZoneValid("-06:00", "Mexico/General", Tr("General"))
checkZoneValid("-06:00", "Pacific/Easter", Tr("Easter Island"))
checkZoneValid("-06:00", "Pacific/Galapagos", Tr("Galapagos"))
//checkZoneValid("-06:00", "US/Central", Tr("US/Central"))
checkZoneValid("-06:00", "US/Indiana-Starke", Tr("Indiana-Starke"))
checkZoneValid("-05:00", "America/Atikokan", Tr("Atikokan"))
checkZoneValid("-05:00", "America/Bogota", Tr("Bogota"))
checkZoneValid("-05:00", "America/Cayman", Tr("Cayman"))
checkZoneValid("-05:00", "America/Coral_Harbour", Tr("Coral Harbour"))
checkZoneValid("-05:00", "America/Detroit", Tr("Detroit"))
checkZoneValid("-05:00", "America/Eirunepe", Tr("Eirunepe"))
checkZoneValid("-05:00", "America/Fort_Wayne", Tr("Fort Wayne"))
checkZoneValid("-05:00", "America/Grand_Turk", Tr("Grand Turk"))
checkZoneValid("-05:00", "America/Guayaquil", Tr("Guayaquil"))
checkZoneValid("-05:00", "America/Havana", Tr("Havana"))
//checkZoneValid("-05:00", "America/Indiana/Indianapolis", Tr("Indiana/Indianapolis"))
checkZoneValid("-05:00", "America/Indiana/Marengo", Tr("Marengo"))
checkZoneValid("-05:00", "America/Indiana/Petersburg", Tr("Petersburg"))
checkZoneValid("-05:00", "America/Indiana/Vevay", Tr("Vevay"))
checkZoneValid("-05:00", "America/Indiana/Vincennes", Tr("Vincennes"))
checkZoneValid("-05:00", "America/Indiana/Winamac", Tr("Winamac"))
checkZoneValid("-05:00", "America/Indianapolis", Tr("Indianapolis"))
checkZoneValid("-05:00", "America/Iqaluit", Tr("Iqaluit"))
checkZoneValid("-05:00", "America/Jamaica", Tr("Jamaica"))
//checkZoneValid("-05:00", "America/Kentucky/Louisville", Tr("Kentucky/Louisville"))
checkZoneValid("-05:00", "America/Kentucky/Monticello", Tr("Monticello"))
checkZoneValid("-05:00", "America/Lima", Tr("Lima"))
checkZoneValid("-05:00", "America/Louisville", Tr("Louisville"))
checkZoneValid("-05:00", "America/Montreal", Tr("Montreal"))
checkZoneValid("-05:00", "America/Nassau", Tr("Nassau"))
checkZoneValid("-05:00", "America/New_York", Tr("New York"))
checkZoneValid("-05:00", "America/Nipigon", Tr("Nipigon"))
checkZoneValid("-05:00", "America/Panama", Tr("Panama"))
checkZoneValid("-05:00", "America/Pangnirtung", Tr("Pangnirtung"))
checkZoneValid("-05:00", "America/Port-au-Prince", Tr("Port-au-Prince"))
checkZoneValid("-05:00", "America/Porto_Acre", Tr("Porto Acre"))
checkZoneValid("-05:00", "America/Rio_Branco", Tr("Rio Branco"))
checkZoneValid("-05:00", "America/Thunder_Bay", Tr("Thunder Bay"))
checkZoneValid("-05:00", "America/Toronto", Tr("Toronto"))
checkZoneValid("-05:00", "Brazil/Acre", Tr("Acre"))
checkZoneValid("-05:00", "Canada/Eastern", Tr("Canada/Eastern"))
checkZoneValid("-05:00", "Cuba", Tr("Cuba"))
//checkZoneValid("-05:00", "Jamaica", Tr("Jamaica"))
checkZoneValid("-05:00", "US/Eastern", Tr("US/Eastern"))
checkZoneValid("-05:00", "US/East-Indiana", Tr("East-Indiana"))
checkZoneValid("-05:00", "US/Michigan", Tr("Michigan"))
checkZoneValid("-04:30", "America/Caracas", Tr("Caracas"))
checkZoneValid("-04:00", "America/Anguilla", Tr("Anguilla"))
checkZoneValid("-04:00", "America/Antigua", Tr("Antigua"))
checkZoneValid("-04:00", "America/Aruba", Tr("Aruba"))
checkZoneValid("-04:00", "America/Asuncion", Tr("Asuncion"))
checkZoneValid("-04:00", "America/Barbados", Tr("Barbados"))
checkZoneValid("-04:00", "America/Blanc-Sablon", Tr("Blanc-Sablon"))
checkZoneValid("-04:00", "America/Boa_Vista", Tr("Boa Vista"))
checkZoneValid("-04:00", "America/Campo_Grande", Tr("Campo Grande"))
checkZoneValid("-04:00", "America/Cuiaba", Tr("Cuiaba"))
checkZoneValid("-04:00", "America/Curacao", Tr("Curacao"))
checkZoneValid("-04:00", "America/Dominica", Tr("Dominica"))
checkZoneValid("-04:00", "America/Glace_Bay", Tr("Glace Bay"))
checkZoneValid("-04:00", "America/Goose_Bay", Tr("Goose Bay"))
checkZoneValid("-04:00", "America/Grenada", Tr("Grenada"))
checkZoneValid("-04:00", "America/Guadeloupe", Tr("Guadeloupe"))
checkZoneValid("-04:00", "America/Guyana", Tr("Guyana"))
checkZoneValid("-04:00", "America/Halifax", Tr("Halifax"))
checkZoneValid("-04:00", "America/Kralendijk", Tr("Kralendijk"))
checkZoneValid("-04:00", "America/La_Paz", Tr("La Paz"))
checkZoneValid("-04:00", "America/Lower_Princes", Tr("Lower Princes"))
checkZoneValid("-04:00", "America/Manaus", Tr("Manaus"))
checkZoneValid("-04:00", "America/Marigot", Tr("Marigot"))
checkZoneValid("-04:00", "America/Martinique", Tr("Martinique"))
checkZoneValid("-04:00", "America/Moncton", Tr("Moncton"))
checkZoneValid("-04:00", "America/Montserrat", Tr("Montserrat"))
checkZoneValid("-04:00", "America/Port_of_Spain", Tr("Port of Spain"))
checkZoneValid("-04:00", "America/Porto_Velho", Tr("Porto Velho"))
checkZoneValid("-04:00", "America/Puerto_Rico", Tr("Puerto Rico"))
checkZoneValid("-04:00", "America/Santiago", Tr("Santiago"))
checkZoneValid("-04:00", "America/Santo_Domingo", Tr("Santo Domingo"))
checkZoneValid("-04:00", "America/St_Barthelemy", Tr("St Barthelemy"))
checkZoneValid("-04:00", "America/St_Kitts", Tr("St Kitts"))
checkZoneValid("-04:00", "America/St_Lucia", Tr("St Lucia"))
checkZoneValid("-04:00", "America/St_Thomas", Tr("St Thomas"))
checkZoneValid("-04:00", "America/St_Vincent", Tr("St Vincent"))
checkZoneValid("-04:00", "America/Thule", Tr("Thule"))
checkZoneValid("-04:00", "America/Tortola", Tr("Tortola"))
checkZoneValid("-04:00", "America/Virgin", Tr("Virgin"))
checkZoneValid("-04:00", "Antarctica/Palmer", Tr("Palmer"))
checkZoneValid("-04:00", "Atlantic/Bermuda", Tr("Bermuda"))
checkZoneValid("-04:00", "Brazil/West", Tr("Brazil/West"))
checkZoneValid("-04:00", "Canada/Atlantic", Tr("Atlantic"))
checkZoneValid("-04:00", "Chile/Continental", Tr("Continental"))
checkZoneValid("-03:30", "America/St_Johns", Tr("St Johns"))
checkZoneValid("-03:30", "Canada/Newfoundland", Tr("Newfoundland"))
checkZoneValid("-03:00", "America/Araguaina", Tr("Araguaina"))
//checkZoneValid("-03:00", "America/Argentina/Buenos_Aires", Tr("Argentina/Buenos Aires"))
//checkZoneValid("-03:00", "America/Argentina/Catamarca", Tr("Argentina/Catamarca"))
checkZoneValid("-03:00", "America/Argentina/ComodRivadavia", Tr("ComodRivadavia"))
//checkZoneValid("-03:00", "America/Argentina/Cordoba", Tr("Argentina/Cordoba"))
//checkZoneValid("-03:00", "America/Argentina/Jujuy", Tr("Argentina/Jujuy"))
checkZoneValid("-03:00", "America/Argentina/La_Rioja", Tr("La Rioja"))
//checkZoneValid("-03:00", "America/Argentina/Mendoza", Tr("Argentina/Mendoza"))
checkZoneValid("-03:00", "America/Argentina/Rio_Gallegos", Tr("Rio Gallegos"))
checkZoneValid("-03:00", "America/Argentina/Salta", Tr("Salta"))
checkZoneValid("-03:00", "America/Argentina/San_Juan", Tr("San Juan"))
checkZoneValid("-03:00", "America/Argentina/San_Luis", Tr("San Luis"))
checkZoneValid("-03:00", "America/Argentina/Tucuman", Tr("Tucuman"))
checkZoneValid("-03:00", "America/Argentina/Ushuaia", Tr("Ushuaia"))
checkZoneValid("-03:00", "America/Bahia", Tr("Bahia"))
checkZoneValid("-03:00", "America/Belem", Tr("Belem"))
checkZoneValid("-03:00", "America/Buenos_Aires", Tr("Buenos Aires"))
checkZoneValid("-03:00", "America/Catamarca", Tr("Catamarca"))
checkZoneValid("-03:00", "America/Cayenne", Tr("Cayenne"))
checkZoneValid("-03:00", "America/Cordoba", Tr("Cordoba"))
checkZoneValid("-03:00", "America/Fortaleza", Tr("Fortaleza"))
checkZoneValid("-03:00", "America/Godthab", Tr("Godthab"))
checkZoneValid("-03:00", "America/Jujuy", Tr("Jujuy"))
checkZoneValid("-03:00", "America/Maceio", Tr("Maceio"))
checkZoneValid("-03:00", "America/Mendoza", Tr("Mendoza"))
checkZoneValid("-03:00", "America/Miquelon", Tr("Miquelon"))
checkZoneValid("-03:00", "America/Montevideo", Tr("Montevideo"))
checkZoneValid("-03:00", "America/Paramaribo", Tr("Paramaribo"))
checkZoneValid("-03:00", "America/Recife", Tr("Recife"))
checkZoneValid("-03:00", "America/Rosario", Tr("Rosario"))
checkZoneValid("-03:00", "America/Santarem", Tr("Santarem"))
checkZoneValid("-03:00", "America/Sao_Paulo", Tr("Sao Paulo"))
checkZoneValid("-03:00", "Antarctica/Rothera", Tr("Rothera"))
checkZoneValid("-03:00", "Atlantic/Stanley", Tr("Stanley"))
checkZoneValid("-03:00", "Brazil/East", Tr("Brazil East"))
//checkZoneValid("-02:00", "America/Noronha", Tr("Americaoronha"))
checkZoneValid("-02:00", "Atlantic/South_Georgia", Tr("South Georgia"))
checkZoneValid("-02:00", "Brazil/DeNoronha", Tr("DeNoronha"))
checkZoneValid("-01:00", "America/Scoresbysund", Tr("Scoresbysund"))
checkZoneValid("-01:00", "Atlantic/Azores", Tr("Azores"))
checkZoneValid("-01:00", "Atlantic/Cape_Verde", Tr("Cape Verde"))
checkZoneValid("+00:00", "Africa/Abidjan", Tr("Abidjan"))
checkZoneValid("+00:00", "Africa/Accra", Tr("Accra"))
checkZoneValid("+00:00", "Africa/Bamako", Tr("Bamako"))
checkZoneValid("+00:00", "Africa/Banjul", Tr("Banjul"))
checkZoneValid("+00:00", "Africa/Bissau", Tr("Bissau"))
checkZoneValid("+00:00", "Africa/Casablanca", Tr("Casablanca"))
checkZoneValid("+00:00", "Africa/Conakry", Tr("Conakry"))
checkZoneValid("+00:00", "Africa/Dakar", Tr("Dakar"))
checkZoneValid("+00:00", "Africa/El_Aaiun", Tr("El Aaiun"))
checkZoneValid("+00:00", "Africa/Freetown", Tr("Freetown"))
checkZoneValid("+00:00", "Africa/Lome", Tr("Lome"))
checkZoneValid("+00:00", "Africa/Monrovia", Tr("Monrovia"))
checkZoneValid("+00:00", "Africa/Nouakchott", Tr("Nouakchott"))
checkZoneValid("+00:00", "Africa/Ouagadougou", Tr("Ouagadougou"))
checkZoneValid("+00:00", "Africa/Sao_Tome", Tr("Sao Tome"))
checkZoneValid("+00:00", "Africa/Timbuktu", Tr("Timbuktu"))
checkZoneValid("+00:00", "America/Danmarkshavn", Tr("Danmarkshavn"))
checkZoneValid("+00:00", "Antarctica/Troll", Tr("Troll"))
checkZoneValid("+00:00", "Atlantic/Canary", Tr("Canary"))
//checkZoneValid("+00:00", "Atlantic/Faeroe", Tr("Faeroe"))
checkZoneValid("+00:00", "Atlantic/Faroe", Tr("Faroe"))
checkZoneValid("+00:00", "Atlantic/Madeira", Tr("Madeira"))
checkZoneValid("+00:00", "Atlantic/Reykjavik", Tr("Reykjavik"))
checkZoneValid("+00:00", "Atlantic/St_Helena", Tr("St Helena"))
checkZoneValid("+00:00", "Eire", Tr("Eire"))
//checkZoneValid("+00:00", "Etc/GMT", Tr("GMT"))
//checkZoneValid("+00:00", "Etc/GMT+0", Tr("GMT+0"))
//checkZoneValid("+00:00", "Etc/UCT", Tr("UCT"))
//checkZoneValid("+00:00", "Etc/Universal", Tr("Universal"))
//checkZoneValid("+00:00", "Etc/UTC", Tr("UTC"))
//checkZoneValid("+00:00", "Etc/Zulu", Tr("Zulu"))
checkZoneValid("+00:00", "Europe/Belfast", Tr("Belfast"))
checkZoneValid("+00:00", "Europe/Dublin", Tr("Dublin"))
checkZoneValid("+00:00", "Europe/Guernsey", Tr("Guernsey"))
checkZoneValid("+00:00", "Europe/Isle_of_Man", Tr("Isle of Man"))
checkZoneValid("+00:00", "Europe/Jersey", Tr("Jersey"))
checkZoneValid("+00:00", "Europe/Lisbon", Tr("Lisbon"))
checkZoneValid("+00:00", "GB", Tr("GB"))
checkZoneValid("+00:00", "GB-Eire", Tr("GB-Eire"))
checkZoneValid("+00:00", "GMT", Tr("GMT"))
//checkZoneValid("+00:00", "GMT+0", Tr("GMT+0"))
//checkZoneValid("+00:00", "GMT0", Tr("GMT0"))
//checkZoneValid("+00:00", "GMT-0", Tr("GMT-0"))
checkZoneValid("+00:00", "Greenwich", Tr("Greenwich"))
checkZoneValid("+00:00", "Iceland", Tr("Iceland"))
checkZoneValid("+00:00", "Portugal", Tr("Portugal"))
checkZoneValid("+00:00", "UCT", Tr("UCT"))
checkZoneValid("+00:00", "Universal", Tr("Universal"))
checkZoneValid("+00:00", "UTC", Tr("UTC"))
checkZoneValid("+00:00", "Zulu", Tr("Zulu"))
checkZoneValid("+01:00", "Africa/Algiers", Tr("Algiers"))
checkZoneValid("+01:00", "Africa/Bangui", Tr("Bangui"))
checkZoneValid("+01:00", "Africa/Brazzaville", Tr("Brazzaville"))
checkZoneValid("+01:00", "Africa/Ceuta", Tr("Ceuta"))
checkZoneValid("+01:00", "Africa/Douala", Tr("Douala"))
checkZoneValid("+01:00", "Africa/Kinshasa", Tr("Kinshasa"))
checkZoneValid("+01:00", "Africa/Lagos", Tr("Lagos"))
checkZoneValid("+01:00", "Africa/Libreville", Tr("Libreville"))
checkZoneValid("+01:00", "Africa/Luanda", Tr("Luanda"))
checkZoneValid("+01:00", "Africa/Malabo", Tr("Malabo"))
checkZoneValid("+01:00", "Africa/Ndjamena", Tr("Ndjamena"))
checkZoneValid("+01:00", "Africa/Niamey", Tr("Niamey"))
checkZoneValid("+01:00", "Africa/Porto-Novo", Tr("Porto-Novo"))
checkZoneValid("+01:00", "Africa/Tunis", Tr("Tunis"))
checkZoneValid("+01:00", "Africa/Windhoek", Tr("Windhoek"))
checkZoneValid("+01:00", "Arctic/Longyearbyen", Tr("Longyearbyen"))
checkZoneValid("+01:00", "Atlantic/Jan_Mayen", Tr("Jan Mayen"))
checkZoneValid("+01:00", "Europe/Amsterdam", Tr("Amsterdam"))
checkZoneValid("+01:00", "Europe/Andorra", Tr("Andorra"))
checkZoneValid("+01:00", "Europe/Belgrade", Tr("Belgrade"))
checkZoneValid("+01:00", "Europe/Berlin", Tr("Berlin"))
checkZoneValid("+01:00", "Europe/Bratislava", Tr("Bratislava"))
checkZoneValid("+01:00", "Europe/Brussels", Tr("Brussels"))
checkZoneValid("+01:00", "Europe/Budapest", Tr("Budapest"))
checkZoneValid("+01:00", "Europe/Busingen", Tr("Busingen"))
checkZoneValid("+01:00", "Europe/Copenhagen", Tr("Copenhagen"))
checkZoneValid("+01:00", "Europe/Gibraltar", Tr("Gibraltar"))
checkZoneValid("+01:00", "Europe/Ljubljana", Tr("Ljubljana"))
checkZoneValid("+01:00", "Europe/Luxembourg", Tr("Luxembourg"))
checkZoneValid("+01:00", "Europe/Madrid", Tr("Madrid"))
checkZoneValid("+01:00", "Europe/Malta", Tr("Malta"))
checkZoneValid("+01:00", "Europe/Monaco", Tr("Monaco"))
checkZoneValid("+01:00", "Europe/Oslo", Tr("Oslo"))
checkZoneValid("+01:00", "Europe/Paris", Tr("Paris"))
checkZoneValid("+01:00", "Europe/Podgorica", Tr("Podgorica"))
checkZoneValid("+01:00", "Europe/Prague", Tr("Prague"))
checkZoneValid("+01:00", "Europe/Rome", Tr("Rome"))
checkZoneValid("+01:00", "Europe/San_Marino", Tr("San Marino"))
checkZoneValid("+01:00", "Europe/Sarajevo", Tr("Sarajevo"))
checkZoneValid("+01:00", "Europe/Skopje", Tr("Skopje"))
checkZoneValid("+01:00", "Europe/Stockholm", Tr("Stockholm"))
checkZoneValid("+01:00", "Europe/Tirane", Tr("Tirane"))
checkZoneValid("+01:00", "Europe/Vaduz", Tr("Vaduz"))
checkZoneValid("+01:00", "Europe/Vatican", Tr("Vatican"))
checkZoneValid("+01:00", "Europe/Vienna", Tr("Vienna"))
checkZoneValid("+01:00", "Europe/Warsaw", Tr("Warsaw"))
checkZoneValid("+01:00", "Europe/Zagreb", Tr("Zagreb"))
checkZoneValid("+01:00", "Europe/Zurich", Tr("Zurich"))
checkZoneValid("+01:00", "Poland", Tr("Poland"))
checkZoneValid("+02:00", "Africa/Blantyre", Tr("Blantyre"))
checkZoneValid("+02:00", "Africa/Bujumbura", Tr("Bujumbura"))
checkZoneValid("+02:00", "Africa/Cairo", Tr("Cairo"))
checkZoneValid("+02:00", "Africa/Gaborone", Tr("Gaborone"))
checkZoneValid("+02:00", "Africa/Harare", Tr("Harare"))
checkZoneValid("+02:00", "Africa/Johannesburg", Tr("Johannesburg"))
checkZoneValid("+02:00", "Africa/Kigali", Tr("Kigali"))
checkZoneValid("+02:00", "Africa/Lubumbashi", Tr("Lubumbashi"))
checkZoneValid("+02:00", "Africa/Lusaka", Tr("Lusaka"))
checkZoneValid("+02:00", "Africa/Maputo", Tr("Maputo"))
checkZoneValid("+02:00", "Africa/Maseru", Tr("Maseru"))
checkZoneValid("+02:00", "Africa/Mbabane", Tr("Mbabane"))
checkZoneValid("+02:00", "Africa/Tripoli", Tr("Tripoli"))
checkZoneValid("+02:00", "Asia/Amman", Tr("Amman"))
checkZoneValid("+02:00", "Asia/Beirut", Tr("Beirut"))
checkZoneValid("+02:00", "Asia/Damascus", Tr("Damascus"))
checkZoneValid("+02:00", "Asia/Gaza", Tr("Gaza"))
checkZoneValid("+02:00", "Asia/Hebron", Tr("Hebron"))
checkZoneValid("+02:00", "Asia/Istanbul", Tr("Istanbul"))
checkZoneValid("+02:00", "Asia/Jerusalem", Tr("Jerusalem"))
checkZoneValid("+02:00", "Asia/Nicosia", Tr("Nicosia"))
checkZoneValid("+02:00", "Asia/Tel_Aviv", Tr("Tel Aviv"))
checkZoneValid("+02:00", "Egypt", Tr("Egypt"))
checkZoneValid("+02:00", "Europe/Athens", Tr("Athens"))
checkZoneValid("+02:00", "Europe/Bucharest", Tr("Bucharest"))
checkZoneValid("+02:00", "Europe/Chisinau", Tr("Chisinau"))
checkZoneValid("+02:00", "Europe/Helsinki", Tr("Helsinki"))
//checkZoneValid("+02:00", "Europe/Istanbul", Tr("Istanbul"))
checkZoneValid("+02:00", "Europe/Kiev", Tr("Kiev"))
checkZoneValid("+02:00", "Europe/Mariehamn", Tr("Mariehamn"))
//checkZoneValid("+02:00", "Europe/Nicosia", Tr("Nicosia"))
checkZoneValid("+02:00", "Europe/Riga", Tr("Riga"))
checkZoneValid("+02:00", "Europe/Sofia", Tr("Sofia"))
checkZoneValid("+02:00", "Europe/Tallinn", Tr("Tallinn"))
checkZoneValid("+02:00", "Europe/Tiraspol", Tr("Tiraspol"))
checkZoneValid("+02:00", "Europe/Uzhgorod", Tr("Uzhgorod"))
checkZoneValid("+02:00", "Europe/Vilnius", Tr("Vilnius"))
checkZoneValid("+02:00", "Europe/Zaporozhye", Tr("Zaporozhye"))
checkZoneValid("+02:00", "Israel", Tr("Israel"))
checkZoneValid("+02:00", "Libya", Tr("Libya"))
checkZoneValid("+02:00", "Turkey", Tr("Turkey"))
checkZoneValid("+03:00", "Africa/Addis_Ababa", Tr("Addis Ababa"))
checkZoneValid("+03:00", "Africa/Asmara", Tr("Asmara"))
//checkZoneValid("+03:00", "Africa/Asmera", Tr("Asmera"))
checkZoneValid("+03:00", "Africa/Dar_es_Salaam", Tr("Dar es Salaam"))
checkZoneValid("+03:00", "Africa/Djibouti", Tr("Djibouti"))
checkZoneValid("+03:00", "Africa/Juba", Tr("Juba"))
checkZoneValid("+03:00", "Africa/Kampala", Tr("Kampala"))
checkZoneValid("+03:00", "Africa/Khartoum", Tr("Khartoum"))
checkZoneValid("+03:00", "Africa/Mogadishu", Tr("Mogadishu"))
checkZoneValid("+03:00", "Africa/Nairobi", Tr("Nairobi"))
checkZoneValid("+03:00", "Antarctica/Syowa", Tr("Syowa"))
checkZoneValid("+03:00", "Asia/Aden", Tr("Aden"))
checkZoneValid("+03:00", "Asia/Baghdad", Tr("Baghdad"))
checkZoneValid("+03:00", "Asia/Bahrain", Tr("Bahrain"))
checkZoneValid("+03:00", "Asia/Kuwait", Tr("Kuwait"))
checkZoneValid("+03:00", "Asia/Qatar", Tr("Qatar"))
checkZoneValid("+03:00", "Asia/Riyadh", Tr("Riyadh"))
checkZoneValid("+03:00", "Europe/Kaliningrad", Tr("Kaliningrad"))
checkZoneValid("+03:00", "Europe/Minsk", Tr("Minsk"))
checkZoneValid("+03:00", "Indian/Antananarivo", Tr("Antananarivo"))
checkZoneValid("+03:00", "Indian/Comoro", Tr("Comoro"))
checkZoneValid("+03:00", "Indian/Mayotte", Tr("Mayotte"))
checkZoneValid("+03:30", "Asia/Tehran", Tr("Tehran"))
checkZoneValid("+03:30", "Iran", Tr("Iran"))
checkZoneValid("+04:00", "Asia/Baku", Tr("Baku"))
checkZoneValid("+04:00", "Asia/Dubai", Tr("Dubai"))
checkZoneValid("+04:00", "Asia/Muscat", Tr("Muscat"))
checkZoneValid("+04:00", "Asia/Tbilisi", Tr("Tbilisi"))
checkZoneValid("+04:00", "Asia/Yerevan", Tr("Yerevan"))
checkZoneValid("+04:00", "Europe/Moscow", Tr("Moscow"))
checkZoneValid("+04:00", "Europe/Samara", Tr("Samara"))
checkZoneValid("+04:00", "Europe/Simferopol", Tr("Simferopol"))
checkZoneValid("+04:00", "Europe/Volgograd", Tr("Volgograd"))
checkZoneValid("+04:00", "Indian/Mahe", Tr("Mahe"))
checkZoneValid("+04:00", "Indian/Mauritius", Tr("Mauritius"))
checkZoneValid("+04:00", "Indian/Reunion", Tr("Reunion"))
checkZoneValid("+04:00", "W-SU", Tr("W-SU"))
checkZoneValid("+04:30", "Asia/Kabul", Tr("Kabul"))
checkZoneValid("+14:00", "Pacific/Kiritimati", Tr("Kiritimati"))
checkZoneValid("+05:00", "Antarctica/Davis", Tr("Davis"))
checkZoneValid("+05:00", "Antarctica/Mawson", Tr("Mawson"))
checkZoneValid("+05:00", "Asia/Aqtau", Tr("Aqtau"))
checkZoneValid("+05:00", "Asia/Aqtobe", Tr("Aqtobe"))
checkZoneValid("+05:00", "Asia/Ashgabat", Tr("Ashgabat"))
//checkZoneValid("+05:00", "Asia/Ashkhabad", Tr("Ashkhabad"))
checkZoneValid("+05:00", "Asia/Dushanbe", Tr("Dushanbe"))
checkZoneValid("+05:00", "Asia/Karachi", Tr("Karachi"))
checkZoneValid("+05:00", "Asia/Oral", Tr("Oral"))
checkZoneValid("+05:00", "Asia/Samarkand", Tr("Samarkand"))
checkZoneValid("+05:00", "Asia/Tashkent", Tr("Tashkent"))
checkZoneValid("+05:00", "Indian/Kerguelen", Tr("Kerguelen"))
checkZoneValid("+05:00", "Indian/Maldives", Tr("Maldives"))
checkZoneValid("+05:30", "Asia/Calcutta", Tr("Calcutta"))
checkZoneValid("+05:30", "Asia/Colombo", Tr("Colombo"))
checkZoneValid("+05:30", "Asia/Kolkata", Tr("Kolkata"))
checkZoneValid("+05:45", "Asia/Kathmandu", Tr("Kathmandu"))
//checkZoneValid("+05:45", "Asia/Katmandu", Tr("Katmandu"))
checkZoneValid("+06:00", "Antarctica/Vostok", Tr("Vostok"))
checkZoneValid("+06:00", "Asia/Almaty", Tr("Almaty"))
checkZoneValid("+06:00", "Asia/Bishkek", Tr("Bishkek"))
//checkZoneValid("+06:00", "Asia/Dacca", Tr("Dacca"))
checkZoneValid("+06:00", "Asia/Dhaka", Tr("Dhaka"))
checkZoneValid("+06:00", "Asia/Qyzylorda", Tr("Qyzylorda"))
//checkZoneValid("+06:00", "Asia/Thimbu", Tr("Thimbu"))
checkZoneValid("+06:00", "Asia/Thimphu", Tr("Thimphu"))
checkZoneValid("+06:00", "Asia/Yekaterinburg", Tr("Yekaterinburg"))
checkZoneValid("+06:00", "Indian/Chagos", Tr("Chagos"))
checkZoneValid("+06:30", "Asia/Rangoon", Tr("Rangoon"))
checkZoneValid("+06:30", "Indian/Cocos", Tr("Cocos"))
checkZoneValid("+07:00", "Asia/Bangkok", Tr("Bangkok"))
checkZoneValid("+07:00", "Asia/Ho_Chi_Minh", Tr("Ho Chi Minh"))
checkZoneValid("+07:00", "Asia/Hovd", Tr("Hovd"))
checkZoneValid("+07:00", "Asia/Jakarta", Tr("Jakarta"))
checkZoneValid("+07:00", "Asia/Novokuznetsk", Tr("Novokuznetsk"))
checkZoneValid("+07:00", "Asia/Novosibirsk", Tr("Novosibirsk"))
checkZoneValid("+07:00", "Asia/Omsk", Tr("Omsk"))
checkZoneValid("+07:00", "Asia/Phnom_Penh", Tr("Phnom Penh"))
checkZoneValid("+07:00", "Asia/Pontianak", Tr("Pontianak"))
checkZoneValid("+07:00", "Asia/Saigon", Tr("Saigon"))
checkZoneValid("+07:00", "Asia/Vientiane", Tr("Vientiane"))
checkZoneValid("+07:00", "Indian/Christmas", Tr("Christmas"))
checkZoneValid("+08:00", "Asia/Brunei", Tr("Brunei"))
checkZoneValid("+08:00", "Asia/Choibalsan", Tr("Choibalsan"))
checkZoneValid("+08:00", "Asia/Chongqing", Tr("Chongqing"))
//checkZoneValid("+08:00", "Asia/Chungking", Tr("Chungking"))
checkZoneValid("+08:00", "Asia/Harbin", Tr("Harbin"))
checkZoneValid("+08:00", "Asia/Hong_Kong", Tr("Hong Kong"))
checkZoneValid("+08:00", "Asia/Kashgar", Tr("Kashgar"))
checkZoneValid("+08:00", "Asia/Krasnoyarsk", Tr("Krasnoyarsk"))
checkZoneValid("+08:00", "Asia/Kuala_Lumpur", Tr("Kuala Lumpur"))
checkZoneValid("+08:00", "Asia/Kuching", Tr("Kuching"))
checkZoneValid("+08:00", "Asia/Macao", Tr("Macao"))
//checkZoneValid("+08:00", "Asia/Macau", Tr("Macau"))
checkZoneValid("+08:00", "Asia/Makassar", Tr("Makassar"))
checkZoneValid("+08:00", "Asia/Manila", Tr("Manila"))
checkZoneValid("+08:00", "Asia/Shanghai", Tr("Shanghai"))
checkZoneValid("+08:00", "Asia/Beijing", Tr("Beijing"))
checkZoneValid("+08:00", "Asia/Singapore", Tr("Singapore"))
checkZoneValid("+08:00", "Asia/Taipei", Tr("Taipei"))
checkZoneValid("+08:00", "Asia/Ujung_Pandang", Tr("Ujung Pandang"))
//checkZoneValid("+08:00", "Asia/Ulaanbaatar", Tr("Ulaanbaatar"))
checkZoneValid("+08:00", "Asia/Ulan_Bator", Tr("Ulan Bator"))
checkZoneValid("+08:00", "Asia/Urumqi", Tr("Urumqi"))
checkZoneValid("+08:00", "Australia/Perth", Tr("Perth"))
checkZoneValid("+08:00", "Australia/West", Tr("Australia/West"))
//checkZoneValid("+08:00", "Hongkong", Tr("Hongkong"))
checkZoneValid("+08:00", "PRC", Tr("PRC"))
checkZoneValid("+08:00", "ROC", Tr("ROC"))
//checkZoneValid("+08:00", "Singapore", Tr("Singapore"))
checkZoneValid("+08:45", "Australia/Eucla", Tr("Eucla"))
checkZoneValid("+09:00", "Asia/Dili", Tr("Dili"))
checkZoneValid("+09:00", "Asia/Irkutsk", Tr("Irkutsk"))
checkZoneValid("+09:00", "Asia/Jayapura", Tr("Jayapura"))
checkZoneValid("+09:00", "Asia/Pyongyang", Tr("Pyongyang"))
checkZoneValid("+09:00", "Asia/Seoul", Tr("Seoul"))
checkZoneValid("+09:00", "Asia/Tokyo", Tr("Tokyo"))
checkZoneValid("+09:00", "Japan", Tr("Japan"))
checkZoneValid("+09:00", "Pacific/Palau", Tr("Palau"))
checkZoneValid("+09:00", "ROK", Tr("ROK"))
checkZoneValid("+09:30", "Australia/Adelaide", Tr("Adelaide"))
checkZoneValid("+09:30", "Australia/Broken_Hill", Tr("Broke Hill"))
checkZoneValid("+09:30", "Australia/Darwin", Tr("Darwin"))
checkZoneValid("+09:30", "Australia/North", Tr("Australia/North"))
checkZoneValid("+09:30", "Australia/South", Tr("Australia/South"))
checkZoneValid("+09:30", "Australia/Yancowinna", Tr("Yancowinna"))
checkZoneValid("+10:00", "Antarctica/DumontDUrville", Tr("DumontDUrville"))
checkZoneValid("+10:00", "Asia/Khandyga", Tr("Khandyga"))
checkZoneValid("+10:00", "Asia/Yakutsk", Tr("Yakutsk"))
checkZoneValid("+10:00", "Australia/ACT", Tr("ACT"))
checkZoneValid("+10:00", "Australia/Brisbane", Tr("Brisbane"))
checkZoneValid("+10:00", "Australia/Canberra", Tr("Canberra"))
checkZoneValid("+10:00", "Australia/Currie", Tr("Currie"))
checkZoneValid("+10:00", "Australia/Hobart", Tr("Hobart"))
checkZoneValid("+10:00", "Australia/Lindeman", Tr("Lindeman"))
checkZoneValid("+10:00", "Australia/Melbourne", Tr("Melbourne"))
checkZoneValid("+10:00", "Australia/NSW", Tr("NSW"))
checkZoneValid("+10:00", "Australia/Queensland", Tr("Queensland"))
checkZoneValid("+10:00", "Australia/Sydney", Tr("Sydney"))
checkZoneValid("+10:00", "Australia/Tasmania", Tr("Tasmania"))
checkZoneValid("+10:00", "Australia/Victoria", Tr("Victoria"))
checkZoneValid("+10:00", "Pacific/Chuuk", Tr("Chuuk"))
checkZoneValid("+10:00", "Pacific/Guam", Tr("Guam"))
checkZoneValid("+10:00", "Pacific/Port_Moresby", Tr("Port Moresby"))
checkZoneValid("+10:00", "Pacific/Saipan", Tr("Saipan"))
checkZoneValid("+10:00", "Pacific/Truk", Tr("Truk"))
checkZoneValid("+10:00", "Pacific/Yap", Tr("Yap"))
checkZoneValid("+10:30", "Australia/LHI", Tr("LHI"))
checkZoneValid("+10:30", "Australia/Lord_Howe", Tr("Lord Howe"))
checkZoneValid("+11:00", "Antarctica/Casey", Tr("Casey"))
checkZoneValid("+11:00", "Antarctica/Macquarie", Tr("Macquarie"))
checkZoneValid("+11:00", "Asia/Sakhalin", Tr("Sakhalin"))
checkZoneValid("+11:00", "Asia/Ust-Nera", Tr("Ust-Nera"))
checkZoneValid("+11:00", "Asia/Vladivostok", Tr("Vladivostok"))
checkZoneValid("+11:00", "Pacific/Efate", Tr("Efate"))
checkZoneValid("+11:00", "Pacific/Guadalcanal", Tr("Guadalcanal"))
checkZoneValid("+11:00", "Pacific/Kosrae", Tr("Kosrae"))
checkZoneValid("+11:00", "Pacific/Noumea", Tr("Noumea"))
checkZoneValid("+11:00", "Pacific/Pohnpei", Tr("Pohnpei"))
//checkZoneValid("+11:00", "Pacific/Ponape", Tr("Ponape"))
checkZoneValid("+11:30", "Pacific/Norfolk", Tr("Norfolk"))
checkZoneValid("+12:00", "Antarctica/McMurdo", Tr("McMurdo"))
checkZoneValid("+12:00", "Antarctica/South_Pole", Tr("South Pole"))
checkZoneValid("+12:00", "Asia/Anadyr", Tr("Anadyr"))
checkZoneValid("+12:00", "Asia/Kamchatka", Tr("Kamchatka"))
checkZoneValid("+12:00", "Asia/Magadan", Tr("Magadan"))
//checkZoneValid("+12:00", "Kwajalein", Tr("Kwajalein"))
checkZoneValid("+12:00", "NZ", Tr("NZ"))
checkZoneValid("+12:00", "Pacific/Auckland", Tr("Auckland"))
checkZoneValid("+12:00", "Pacific/Fiji", Tr("Fiji"))
checkZoneValid("+12:00", "Pacific/Funafuti", Tr("Funafuti"))
checkZoneValid("+12:00", "Pacific/Kwajalein", Tr("Kwajalein"))
checkZoneValid("+12:00", "Pacific/Majuro", Tr("Majuro"))
checkZoneValid("+12:00", "Pacific/Nauru", Tr("Nauru"))
checkZoneValid("+12:00", "Pacific/Tarawa", Tr("Tarawa"))
checkZoneValid("+12:00", "Pacific/Wake", Tr("Wake"))
checkZoneValid("+12:00", "Pacific/Wallis", Tr("Wallis"))
checkZoneValid("+12:45", "NZ-CHAT", Tr("NZ-CHAT"))
checkZoneValid("+12:45", "Pacific/Chatham", Tr("Chatham"))
checkZoneValid("+13:00", "Pacific/Apia", Tr("Apia"))
checkZoneValid("+13:00", "Pacific/Enderbury", Tr("Enderbury"))
checkZoneValid("+13:00", "Pacific/Fakaofo", Tr("Fakaofo"))
checkZoneValid("+13:00", "Pacific/Tongatapu", Tr("Tongatapu"))
}

View File

@ -0,0 +1,36 @@
US/Alaska;1394362800;1414922400;-28800
America/Juneau;1394362800;1414922400;-28800
Mexico/BajaNorte;1394359200;1414918800;-25200
America/Vancouver;1394359200;1414918800;-25200
America/Chihuahua;1396774800;1414310400;-21600
Mexico/BajaSur;1396774800;1414310400;-21600
America/Mexico_City;1396771200;1414306800;-18000
America/Chicago;1394352000;1414911600;-18000
America/Monterrey;1396771200;1414306800;-18000
America/New_York;1394348400;1414908000;-14400
America/Cuiaba;1392519600;1413691200;-14400
America/Santiago;1398567600;1410062400;-14400
America/Asuncion;1395543600;1412481600;-14400
Canada/Newfoundland;1394343000;1414902600;-9000
Atlantic/Azores;1396141200;1414285200;0
Europe/London;1396141200;1414285200;3600
Europe/Dublin;1396141200;1414285200;3600
Africa/Casablanca;1396144800;1403920800;3600
Atlantic/Madeira;1396141200;1414285200;3600
Europe/Paris;1396141200;1414285200;7200
Europe/Berlin;1396141200;1414285200;7200
Europe/Rome;1396141200;1414285200;7200
Europe/Vienna;1396141200;1414285200;7200
Africa/Cairo;1400191200;1403816400;10800
Europe/Athens;1396141200;1414285200;10800
Europe/Bucharest;1396141200;1414285200;10800
Europe/Istanbul;1396227600;1414285200;10800
Asia/Tehran;1395433800;1411327800;16200
Asia/Baku;1396137600;1414281600;18000
Australia/Sydney;1396713600;1412438400;36000
Australia/Melbourne;1396713600;1412438400;36000
Australia/Hobart;1396713600;1412438400;36000
Australia/Lord_Howe;1396710000;1412436600;37800
Pacific/Auckland;1396706400;1411826400;43200
Pacific/Chatham;1396706400;1411826400;45900
Pacific/Apia;1396706400;1411826400;46800