Java 时间转换问题总结

这几天开发中遇到时间转换出错的问题,特总结如下:
 
==============================================================================
String 到Date转换
==============================================================================
 
 
 在使用“SimpleDateFormat ”进行带星期的日期字符串函数转换时需要指定时区,如果不指定时区将会抛出异常
 
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
 
String da1 = "Tue 02-Apr-2013 19:00";
SimpleDateFormat sdf_wrong = new SimpleDateFormat("EEE dd-MMM-yyyy HH:mm");
Date d1 = sdf_wrong.parse(da1);//抛出异常;
 
SimpleDateFormat sdf_right = new SimpleDateFormat("EEE dd-MMM-yyyy HH:mm",Locale.ENGLISH);
Date d1 = sdf_right.parse(da1);//正确;
 
函数参数返回值说明:
public SimpleDateFormat(String pattern,
                        Locale locale)
Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the given locale. Note: This constructor may not support all locales. For full coverage, use the factory methods in the DateFormat class.
Parameters:
pattern - the pattern describing the date and time format
locale - the locale whose date format symbols should be used
Throws:
NullPointerException - if the given pattern or locale is null
IllegalArgumentException - if the given pattern is invalid
函数内部实现:
    /**
     * Constructs a <code>SimpleDateFormat</code> using the given pattern and
     * the default date format symbols for the default
     * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
     * <b>Note:</b> This constructor may not support all locales.
     * For full coverage, use the factory methods in the {@link DateFormat}
     * class.
     * <p>This is equivalent to calling
     * {@link #SimpleDateFormat(String, Locale)
     *     SimpleDateFormat(pattern, Locale.getDefault(Locale.Category.FORMAT))}.
     *
     * @see java.util.Locale#getDefault(java.util.Locale.Category)
     * @see java.util.Locale.Category#FORMAT
     * @param pattern the pattern describing the date and time format
     * @exception NullPointerException if the given pattern is null
     * @exception IllegalArgumentException if the given pattern is invalid
     */
    public SimpleDateFormat(String pattern)
    {
        this(pattern, Locale.getDefault(Locale.Category.FORMAT));
    }
 
    /**
     * Constructs a <code>SimpleDateFormat</code> using the given pattern and
     * the default date format symbols for the given locale.
     * <b>Note:</b> This constructor may not support all locales.
     * For full coverage, use the factory methods in the {@link DateFormat}
     * class.
     *
     * @param pattern the pattern describing the date and time format
     * @param locale the locale whose date format symbols should be used
     * @exception NullPointerException if the given pattern or locale is null
     * @exception IllegalArgumentException if the given pattern is invalid
     */
    public SimpleDateFormat(String pattern, Locale locale)
    {
        if (pattern == null || locale == null) {
            throw new NullPointerException();
        }
 
        initializeCalendar(locale);
        this.pattern = pattern;
        this.formatData = DateFormatSymbols.getInstanceRef(locale);
        this.locale = locale;
        initialize(locale);
    }
 
 
======================================================================================
Date转换为String
======================================================================================
1.现象
startTime = DateUtil.formatDate(child.getStartTime(), "yyyy-MM-dd");  
 
 
传入时间为2015-09-19 00:00:00   而  startTime结果为  2015-09-18
 
 
2.原因分析
 
DateUtil.formatDate默认设置的时区为GMT ,而本地默认时区为CST UT+8:00  这样导致两者相差 8小时(GMT比CST慢8个小时 ) 
 
所以通过该函数转换出的时间看到会相差一天。
 
3.解决方案
 
String startTime = SimpleDateFormat.getDateInstance().format(date);
 
或者
 
String startTime4 = DateFormat.getDateInstance().format(date);
 
避免时区转换问题
 
 
PS: GMT和CST区别
 
GMT 
Greenwich Mean Time 格林尼治标准时间 

很多unix下用date命令都能看到当前的时区。很多unix下中国时区都是用CST表示的。但是这个表示方法非常不合理。因为CST同时代表了下面4个时区。

CST Central Standard Time (USA) UT-6:00
CST Central Standard Time (Australia) UT+9:30
CST China Standard Time UT+8:00
CST Cuba Standard Time UT-4:00
 
 
参考示例:一
 
=====================================================================================================
 
 

CET(欧洲中部时间)

欧洲中部时间(英語:Central European Time,CET)是比世界标准时间(UTC)早一个小时的时区名称之一。它被大部分欧洲国家和部分北非国家采用。

冬季时间为UTC+1,夏季欧洲夏令时为UTC+2。

WET(欧洲西部时间)

欧洲西部时间(Western European Time,缩写WET)和世界标准时间(UTC)相同。

EET(欧洲东部时间)

欧洲东部时间(Eastern European Time,缩写EET)是比世界标准时间(UTC)早二个小时的时区名称之一。它被部分欧洲国家、北非国家和中东国家采用。

UTC(世界标准时间)

协调世界时,又称世界标准时间或世界協調時間,简称UTC(从英文「Coordinated Universal Time」/法文「Temps Universel Cordonné」而来),是最主要的世界時間標準,其以原子时秒长为基础,在时刻上尽量接近于格林尼治平時。

GMT(格林尼治平时)

格林尼治平时(又称格林尼治平均时间或格林尼治标准时间,旧译格林威治标准时间;英语:Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。

自1924年2月5日开始,格林尼治天文台每隔一小时会向全世界发放调时信息。

理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。由于地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能与实际的太阳时有误差,最大误差达16分钟。

由于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治时间已经不再被作为标准时间使用。现在的标准时间,是由原子钟报时的协调世界时(UTC)

CST(北京时间)

北京时间,China Standard Time,中国标准时间。在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8。

不过这个CST这个缩写比较纠结的是它可以同时代表四个不同的时间

  • Central Standard Time (USA) UT-6:00
  • Central Standard Time (Australia) UT+9:30
  • China Standard Time UT+8:00
  • Cuba Standard Time UT-4:00

因此你平时编写程序过程中也有可能遇到javascript客户端时间和服务端时间不一致的问题,编程的时候还是要多注意。

ISO 日期和时间的表示方法

国际标准化组织的国际标准ISO 8601是日期和时间的表示方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》。目前是第三版ISO8601:2004以替代第一版ISO8601:1988與第二版ISO8601:2000。

这是仅仅就只是一个日期时间的表示方法,我们用这样的方法表示一个UTC时间。

 

=============================================================================================

参考示例:二

CST和GMT时间的区别


问题描述 
今天遇到一个奇怪的问题,在服务器端通过 Java 获取当前时间为 Fri Aug 28 09:37:46 CST 2009, 转化为GMT时间为:28 Aug 2009 01:37:46 GMT,也就是说GMT时间加上 8 个小时等于CST表示的时间, 那这个CST不就是北京时间么,因为我们是在东八区的。 

一切看起来很正常,不过在客户端用JavaScript解析这个时间就有问题了: 
1
2
// Fri Aug 28 2009 23:37:46 GMT+0800
new Date('Fri Aug 28 09:37:46 CST 2009').toString();

好奇怪,这次GMT和CST表示的时间居然相差整整 14 个小时? 



百度一下 

找到这篇文章,问题已经很明了。 

GMT(Greenwich Mean Time)代表格林尼治标准时间,这个大家都知道。 
而CST却同时可以代表如下 4 个不同的时区: 
  • Central Standard Time (USA) UT-6:00
  • Central Standard Time (Australia) UT+9:30
  • China Standard Time UT+8:00
  • Cuba Standard Time UT-4:00

可见,CST可以同时表示美国,澳大利亚,中国,古巴四个国家的标准时间。 

前面提到的通过 Java 获取的CST时间用的是China Standard Time,而客户端JavaScript则默认采用的是美国的中部时间。 

所以将 Fri Aug 28 09:37:46 CST 2009 加上 6 个小时,再加上 8 个小时,就等于 Fri Aug 28 2009 23:37:46 GMT+0800 

可见,在以后的编程中为了避免错误,还是不要使用CST时间,而尽量采用GMT时间。
 
 
问题:
1.SimpleDateFormat 中YYYY 导致的week year问题
 
代码:
 
       String time  = "2016-04-12";
// String time2 = "2015-12-31";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat df2 = new SimpleDateFormat("YYYY-MM-dd");

try {
System.out.println("The date yyyy:"+df.parse(time).toString());
System.out.println("The date YYYY:"+df2.parse(time).toString());
} catch (ParseException e) {
e.printStackTrace();
}
OutPut:
 
The date yyyy:Tue Apr 12 00:00:00 CST 2016
The date YYYY:Sun Dec 27 00:00:00 CST 2015
 
 
参考资料:
 
 

Date and Time Patterns

Date and time formats are specified by date and time pattern strings. Within date and time pattern strings, unquoted letters from 'A' to 'Z' and from 'a' to 'z' are interpreted as pattern letters representing the components of a date or time string. Text can be quoted using single quotes (') to avoid interpretation. "''" represents a single quote. All other characters are not interpreted; they're simply copied into the output string during formatting or matched against the input string during parsing.

The following pattern letters are defined (all other characters from 'A' to 'Z' and from 'a' to 'z' are reserved):

LetterDate or Time ComponentPresentationExamples
G Era designator Text AD
y Year Year 199696
Y Week year Year 200909
M Month in year Month JulyJul07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day name in week Text TuesdayTue
u Day number of week (1 = Monday, ..., 7 = Sunday) Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard TimePSTGMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08-0800-08:00
posted @ 2016-08-05 16:31  iByte  阅读(1696)  评论(0编辑  收藏  举报