TimeZone 时区 (JS .NET JSON MYSQL)
来源参考 : http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html
来源参考 : http://walkingice.blogspot.com/2014/08/javascript-timezone.html?m=1 (夏令时)
有些跨国项目有时区计算的要求,虽然我到目前也没接过这种大项目,但还是先了解一下呗!
整个地球分为二十四时区, 从 -12:00 到 +13:00
UTC(Universal Time Coordinated) 就是 +0:00 算是统一的时间制度,
GMT(Greenwich Mean Time) 和 UTC 可以看作是相同的 (它们都是英国伦敦的时间)
PST (pacific standard time -08:00) 也挺红的.
DST ( Daylight Saving Time 夏令时) 不是每个地区都有,它算是一个机制,用于节约能源,做法是在夏季左右把时间调后 1小时,然后又在夏季结束后调回1小时
这个是会影响到时区的,比如 "Sun Mar 09 2014 01:59:00 GMT-0500 (EST)" ->
"Sun Mar 09 2014 03:00:00 GMT-0400 (EDT)" . 2点不会出现,因为时间被调后了1小时, -0500 变 -0400 了
好,基本上有个时区概念了。那么我们来看看在 js,.net,json,mysql 之前它们对于时区的做法的区别。
先说说 javascript 吧 .
var date = new Date(); //返回当前本地时间对象,所以不同地区会有不同结果.
var timezone = date.getTimezoneOffset(); //返回当前地区的时区-分钟 (比如新加坡是 +08:00 , 那么结果就是-480咯,这个是会依据当地的 "夏令时" 的哦!)
var strDate = date.toISOString(); //把日期对象转换成string(并且是UTC的时间),它的各式是 2014-11-23T15:01:31.912Z
var date = new Date("2014-11-23T15:01:31.912Z"); //str to date , Z表示 UTC 所以,它会把时间依据当地时区做+-然后返回日期对象
var date = new Date("2014-11-23T15:01:31.912+01:00"); //+01:00 表示这个时间保存时的时区, 会先把这个时间转去 UTC 在 转去本地. -1小时变成UTC,+8小时变成date(比如新加坡)
//c# 的格式是这样 "yyyy-MM-ddTHH:mm:ss.fffffff%K"
需要清楚string的2种格式写法 (Z 和 +) Z表示日期是个UTC +0:00 , +格式更好,能表示记入时的时区, 之后也还可以转换成UTC
在c# DateTimeOffset.tostring() default 会出这个格式 "yyyy/MM/dd HH:mm:ss %K" js可以处理,
那么在 mssql 中保持的格式是这样的 "yyyy-MM-dd HH:mm:ss.fffffff %K" js不可以处理
那么一般上我们就直接用 toString就好,那么如果真的要出毫秒的话, 那么就用 "yyyy-MM-ddTHH:mm:ss.fffffff%K" 这个js可以处理.
而外说 : SQL server 如果要set default datetimeOffset 的话用 (sysdatetimeoffset())
前端一般上我们要呈现给user看的日期格式是 "yyyy-MM-dd hh:mm:ss a" <- 2014-04-01 08:00:00 AM (angularjs 的 pattern)
在使用 datepicker 时一般上我们是用 "dd-MMM-yyyy" <- 22-May-2015 (angularjs 的 pattern)
还有一种就是什么都没有注明的,既不是Z也不是+ ,那么就不会做任何计算了。
当 date to string 时(包括json化的时候) date 依据当前的时区做+- 然后输出 Z格式.
而 string to date 的话,Z格式会依据当前时区做+- ,而+格式则会先转去UTC在依据当前时区做+-
所以前台 to 后台的话都是用Z格式(UTC)的。
后台 to 前台 则可能是 Z 或者 + , 要看后台的输出了。
.NET 的部分
DateTime now = DateTime.Now; //kind = local
DateTime nowUtc = DateTime.UtcNow; //kind = UTC
TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
DateTimeOffset dateB = new DateTimeOffset(, , , , , , , new TimeSpan(, , ));//kind = unknow
.net 最好是使用 DateTimeOffset 配合 SQL server 的 DateTimeOffset . 但是因为我是用 MYSQL (目前不支持DateTimeOffset,所以下面内容主要针对MYSQL)
date 对象都有一个kind属性表明这个date是local,utc or unknow .
kind UTC ,
-前台的Z格式来到后台被解析后就是 kind utc
-DateTime.UtcNow 返回是 utc
kind Local
-DateTime.Now 返回是 local
-当我们从mysql 的 timestamp类型获取值的时候,kind = local
kind unknow
-当我们从mysql 的 datetime 类型获取值的时候 , kind = unknow
需要注意的是,我们从 mysql select资料放入date 时,日期是不会被做任何计算的,只有kind有区别.
当我们使用JSON.NET做序列化想返回给前台时。它会依据你的kind来决定是要放 + 还是 Z ,但是它不会对你的值做任何计算等. 当遇到unknow的时候它会直接返回一个没有 + 也没有 Z 的格式。
以上这2点容易造成混淆。要注意哦.
基本上只有在 DateTime.Now 时会涉及到server 的local时区时间。MYSQL TO c# or js to c# 都不会做什么计算处理,只要注意标签就好。
JSON.net 和 web service 对于前台的 string "2014-05-05" 是可以直接转换成DateTime的 , hour minute second 是 00:00:00, knid = unknow.
这里提供一个.net中查看时区和convert个个时间时区的方法
DateTime dt = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now, TimeZoneInfo.Local);
dt = TimeZoneInfo.ConvertTimeFromUtc(dt, TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time")); //有考虑到夏令时
List<string> datas = new List<string>();
foreach (TimeZoneInfo timeZoneInfo in TimeZoneInfo.GetSystemTimeZones())
{
//datas.Add(timeZoneInfo.StandardName);
datas.Add(timeZoneInfo.DisplayName);
}
MYSQL
datetime 和 timestamp 的区别。
timestamp 会配合 mysql 的local时区做计算。比如你的timzone是 +02:00 . 那么你放一个 02:00点进去。mysql内部会把它转成UTC保存。当select的时候它会把这个UTC时间依据当前的时区做 +- 输出。(这里也容易混淆,要注意哦)
datetime 则不会被时区影响,它只是简单的保存值。
mysql 有个 set time_zone = '+8:00'; 的指令,可以per connection 的转换时区。
主要是MYSQL 进出的时候配合timezone计算的方式要搞懂.
总结 :
其实上面主要只是做了一些基础知识的记入。方便我自己以后看的。
一般在开发的时候,SQL 和 .net 经可能都用 UTC 时间来做业务处理。这样可以避免不同服务器数据库地点的时区造成的混淆。
那么在通讯方便,可以利用访问数据库的指令接口,让我们每个select 都 set time_zone = '+0:00'; 确保是UTC时间 (如果你权限够,最后直接设置数据库的local time)
那么在序列化的时候也可以通过 json.net converter write json 的接口做一些自定义的处理。
javascript 方面。我们也可以自己重写 Date.prototype.toJson 方法来做统一处理。
对于一些只有date 不需要time的,甚至可以选择用string "yyyy-MM-dd" 来代替 datetime . (这样就避开时区的问题了)
最重要的就是搞清楚状况,按你的需求来设计方案。统一规范,调整每个通讯接口。那么因该就可以解决时区的混淆了.
以后有实际开发的案例我再来重写一篇吧 ^^
以前写的 get work week
Date.prototype.getWorkWeek = function () {
var currentdate = this;
//para is date format
//all years starting on Thursday, and leap years starting on Wednesday; got ww53 in the year
//all years ending on Thursday, and leap years ending on Friday; got ww53 in the year
//可以被4除就是leap year
//If jan1 is on a 1,2,3,4 it is in week 1. If 1 January is on a 5,6,0(7) is week 52 or 53
function checkIsGotWW53(jan1) {
var isLeapYear = jan1.getFullYear() % 4 == 0
var yearStartDay = jan1.getDay();
return yearStartDay == 4 || (isLeapYear && yearStartDay == 3);
}
//先看今年去年有没有53 都会用到
var thisJan1 = new Date(currentdate.getFullYear(), 00, 01);
var isThisYearGotWW53 = checkIsGotWW53(thisJan1);
var lastJan1 = new Date(currentdate.getFullYear() - 1, 00, 01);
var isLastYearGotWW53 = checkIsGotWW53(lastJan1);
//check start day is ww1 or ww52 / 53
//If jan1 is on a 1,2,3,4 it is in week 1. If 1 January is on a 5,6,0(7) is week 52 or 53
var startWW = "";
var startDay = thisJan1.getDay();
if (startDay > 0 && startDay < 5) {
startWW = 1;
}
else if (startDay == 0 || startDay > 4) {
startWW = (isLastYearGotWW53) ? 53 : 52;
}
//首先,拿我选的天去减掉1月号,除7
//condition 1 : 不能除
//condition 2 : 有余数 (如果余数加1月号的星期几 超过 7 那么就要加 1个week )
//condition 3 : 没有余数
//check 去年start ww 是多少再,就可以确定今年1月1号是ww 几,然后在把condition 加进去
var gap = Math.abs(currentdate.subtract(thisJan1).day);
var week = Math.floor(gap / 7);
var leftDay = gap % 7;
if (startDay + leftDay > 7) //抽余数看要不要加多一个week
{
week += 1;
}
if (week != 0) {
if (startWW != 1) {
startWW = 0;
}
startWW += week; //拿start ww 加 相差多少个week
startWW = (!isThisYearGotWW53 && startWW == 53) ? 1 : startWW; //如果今年没有53 而你是53 , 就set to 1
return startWW;
}
else {
return startWW;
}
}
关于闰年
4年一润, 百年不润, 400年再润. so 2100 is not 闰年.
refer:http://www.cnblogs.com/jay-xu33/archive/2009/01/08/1371953.html
TimeZone 时区 (JS .NET JSON MYSQL)的更多相关文章
- TimeZone 时区 (JS .NET JSON MYSQL) + work week 闰年
来源参考 : http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html 来源参考 : http://walkingice.blogs ...
- KoaHub.JS基于Node.js开发的mysql的node.js驱动程序代码
mysql A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 10 ...
- Node.js:连接 MySQL
ylbtech-Node.js:连接 MySQL 1.返回顶部 1. Node.js 连接 MySQL 本章节我们将为大家介绍如何使用 Node.js 来连接 MySQL,并对数据库进行操作. 如果你 ...
- Node.js Express连接mysql完整的登陆注册系统(windows)
windows学习环境: node 版本: v0.10.35 express版本:4.10.0 mysql版本:5.6.21-log 第一部分:安装node .Express(win8系统 需要&qu ...
- Lumen 设置 timezone 时区
Lumen 设置 timezone 时区 2015-06-19| wid| 后端开发 今天用 Lumen 框架写代码时, 也是初次体验 Lumen, 遇到了一个问题, 从数据库里查出的时间比数据库里保 ...
- C#、js、json Datetime格式总结
在工作过程中遇到时间格式的数据在C#.js 和 json保存的不同结果,现在总结一下 JavaScript Parser: 1.数字型时间转字符串时间 如var data = "/Date( ...
- js声明json数据,打印json数据,遍历json数据
1.js声明json数据: 2.打印json数据: 3.遍历json数据 //声明JSON var json = {}; json.a = 1; //第一种赋值方式(仿对象型) json['b'] = ...
- Js中JSON数据交换使用总结
Json格式简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是JavaScript原 ...
- JS操作JSON总结
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...
随机推荐
- 转:有关Java泛型的类型擦除(type erasing)
转载自:拈花微笑 自从Java 5引入泛型之后,Java与C++对于泛型不同的实现的优劣便一直是饭后的谈资.在我之前的很多training中,当讲到Java泛型时总是会和C++的实现比较,一般得出的结 ...
- JAVA ,SSH中文及其乱码问题的解决 6大配置点 使用UTF-8编码
JSP,mysql,tomcat下(基于struts2)中文及其乱码问题的解决 6大配置点 使用UTF-8编码 目前对遇到J2EE 开发中 中文及其乱码问题,参考网上资料做个总结, 主要是6大配置点: ...
- Android 自定义View (二) 进阶
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例 ...
- LA 6449 IQ Test
[题目] 给出一个长度为n的数组(8<n<12),告诉你规律 (1<=d<=3)要求d尽量小 现在求第n+1项 [题解] 水题 不知道怎么求a1~ad? 用克拉默法则 [代码 ...
- Everything 使用技巧
使用技巧 可以使用逻辑符空格(与), |(或),!(非),及通配符 * 和 ? ,符号或搜索内容之间必须加空格且空格任意使用如果经常搜索同一内容,可以使用书签功能,且可以对书签进行添加.编辑.排序.导 ...
- android SQLite使用SQLiteOpenHelper类对数据库进行增删查改
一个简单的例子,当点击按钮时进行相应的操作,效果图如下: 项目代码如下: DatabaseHelper类 package com.example.sqlitedatebasetest; import ...
- Shell中的数值计算
#!/bin/bash echo "please input number:" read n a=`expr $n / 100` #a1=`expr $n - $a * 100` ...
- Oracle中REGEXP_SUBSTR函数(转)
Oracle中REGEXP_SUBSTR函数 Oracle中REGEXP_SUBSTR函数的使用说明: 题目如下:在oracle中,使用一条语句实现将'17,20,23'拆分成'17','20','2 ...
- Terminating app due to uncaught exception 'NSUnknownKeyException', reason: xxxx
出现错误的情景: 使用Swift自定义Cell, 然后将这个Cell在OC中使用, 由于为了能够在OC中使用和使用起来命名比较规范 我在Swift自定义的Cell前加了 @objc(DSProduct ...
- 关于JavaScript对象的键和值
一个JavaScript对象由键和值组成. 当一个给定键的值被设置为一个字符串.布尔值.数字.数组或对象时,我们把这个键称为属性. 当把键设置为函数时,我们把它叫做方法.