来源参考 : 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)的更多相关文章

  1. TimeZone 时区 (JS .NET JSON MYSQL) + work week 闰年

    来源参考 : http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html 来源参考 : http://walkingice.blogs ...

  2. 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 ...

  3. Node.js:连接 MySQL

    ylbtech-Node.js:连接 MySQL 1.返回顶部 1. Node.js 连接 MySQL 本章节我们将为大家介绍如何使用 Node.js 来连接 MySQL,并对数据库进行操作. 如果你 ...

  4. Node.js Express连接mysql完整的登陆注册系统(windows)

    windows学习环境: node 版本: v0.10.35 express版本:4.10.0 mysql版本:5.6.21-log 第一部分:安装node .Express(win8系统 需要&qu ...

  5. Lumen 设置 timezone 时区

    Lumen 设置 timezone 时区 2015-06-19| wid| 后端开发 今天用 Lumen 框架写代码时, 也是初次体验 Lumen, 遇到了一个问题, 从数据库里查出的时间比数据库里保 ...

  6. C#、js、json Datetime格式总结

    在工作过程中遇到时间格式的数据在C#.js 和 json保存的不同结果,现在总结一下 JavaScript Parser: 1.数字型时间转字符串时间 如var data = "/Date( ...

  7. js声明json数据,打印json数据,遍历json数据

    1.js声明json数据: 2.打印json数据: 3.遍历json数据 //声明JSON var json = {}; json.a = 1; //第一种赋值方式(仿对象型) json['b'] = ...

  8. Js中JSON数据交换使用总结

    Json格式简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是JavaScript原 ...

  9. JS操作JSON总结

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...

随机推荐

  1. Migration workstation vms to openstack kvm

    Migration workstation vms to openstack kvm 分别分成(磁盘是否拆分,vms 是否 有多个磁盘驱动器) 1, linux迁移 vmware workstatio ...

  2. Ionic文件目录说明

    hooks   //google之后这个目录应该是在编译cordova时自定义的脚本命令,方便整合到我们的编译系统和版本控制系统中 plugins  //cordova插件的目录,插件的安装下一节详述 ...

  3. Object-C 函数定义 -- 笔记

    -(int) f:(int)x; 1.这里 - 表示对象方法, +表示类的方法 2.参数分割使用 : 号来分开 多参数情况: 1.函数不带参数 (函数名: f) -(int) f 2.带一个参数(函数 ...

  4. C++之static

    一.静态全局变量和非静态全局变量 1. 隐藏作用 比较非静态全局变量和静态(static)全局变量: 对于多个文件的代码,非静态全局变量和函数都是全局可见的.举例如下: a.c中: #include& ...

  5. Android应用程序安装与Launcher启动机制

      以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):http://blog.csdn.net/luoshe ...

  6. PHP编写的SVN类

    <?php /** * SVN 外部命令 类 * * @author rubekid * * @todo comment need addslashes for svn commit * */ ...

  7. LINQ简明教程:数据排序、分组、过滤

    LINQ可以对很多数据源进行查询操作,比如数据库.数组(array).链表(list).XML文件等.在本文中,我将从数组中提取数据,这些数据是10个最受欢迎的国家.有一个类叫Countries,有c ...

  8. 利用CSS实现居中对齐

    1. 文本居中 首先编写一个简单的html代码,设置一个类名为parentDiv的div对象.html代码如下: <div class="parentDiv"> 这里随 ...

  9. drop表,然后创建表,插入数据,并创建索引等内容。

    execute immediate 'drop table sjb_jhgl_ydjhtdsbb';   execute immediate 'create table dw_sc.sjb_jhgl_ ...

  10. C程序第二章节:算法

    1.主要讲了:算法,3种基本结构化的算法(顺序,选择,循环结构),N-S流程图表示算法,伪代码表示算法. 2.输入10个数,输出其中最大的一个数. #include <stdio.h>in ...