日期操作的时候经常会在字符串、毫秒和日期对象间转换,而且很多人都使用joda time库进行操作,这就会遇到以下说的问题(相信很多人也遇到了):就是对于某些特殊的日期,转换的时候会报错,或者出现转换不准确(相差一小时)的问题。

1,字符串转日期,转long

首先,我们先将日期字符串转为日期,再打印出long值,以‘1986-05-04’为例:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
System.out.println(formatter.parseDateTime("1986-05-04").getMillis());

这时就会出现下面的异常:org.joda.time.IllegalInstantException: Cannot parse "1986-05-04": Illegal instant due to time zone offset transition (Asia/Shanghai)

对于一般的日期字符串这样写并不会报错,这种引起报错的特殊日期还不止一个,比如:1988-04-10,1989-04-16,1990-04-15,1991-04-14等。这其实是时区相关的错误,是夏令时引起的,详情参考http://www.bubuko.com/infodetail-997580.html

解决办法:

//1.指定使用UTC时区,但是需要考虑时差
System.out.println(formatter.withZone(DateTimeZone.UTC).parseDateTime(date).getMillis());
System.out.println(formatter.withZone(DateTimeZone.UTC).parseDateTime(date).getMillis()-8*60*60*1000);
//2.转为Local时间
System.out.println(formatter.parseLocalDate(date).toDateTimeAtStartOfDay().getMillis());
System.out.println(formatter.parseLocalDateTime(date).toDate().getTime());
//可以转为LocalDate或者Date,但是不能转为LocalDateTime,否则还是会报错
System.out.println(formatter.parseLocalDateTime(date).toDateTime().getMillis());//会报错

或者,直接使用java.util.Date是不会出现上边的问题的:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf.parse("1986-05-04").getTime());//可以正常打印

使用jdk8增加的time包,也可以,也是需要指定时区的:

DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(LocalDate.parse("1986-05-04", df).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());

2,long转日期,转字符串

接着上边的说,将'1986-05-04'转为long后的结果是515520000000(时区Asia/Shanghai),现在我们再逆向转回去:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(new Date(l))); //打印结果:1986-05-04 01:00:00

打印结果发现问题来了,时间部门变成了01:00:00,多了一个小时(有的日期可能是少一个小时,都是夏令时的原因),使用joda time也是一样:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(new DateTime(l).toString(formatter)); //打印结果:1986-05-04 01:00:00

解决办法:

//还是要借助时区转换,注意补齐时差
System.out.println(new DateTime(l+8*60*60*1000).withZone(DateTimeZone.UTC).toString(formatter));//打印结果:1986-05-04 00:00:00
System.out.println(new DateTime(l+DateTimeZone.getDefault().getOffsetFromLocal(l)).withZone(DateTimeZone.UTC).toString(formatter));//打印结果:1986-05-04 00:00:00

Java小记 —— 日期时间转换问题(相差一小时)相关推荐

  1. JS - UTC时间转换(相差8小时解决方法)

    目录 前言 修改方法 前言 后端返回的UTC时间格式 2021-09-03T22:42:05.659+00:00 前端格式化后发现多了8小时: 2021/09/04 06:42:05 其原因是北京时间 ...

  2. java calendar格式化_Java:日期时间转换与格式化

    Java:日期时间转换与格式化 2020-08-12 21:28:58 一.Java中时间类 1.Date类 Date常用的构造函数: Date()生成一个代表当前日期时间的Date对象,相当于Dat ...

  3. Java时间工具类(把日期时间转换成xx秒前、xx分钟前、xx小时前...)

    Java时间工具类(把日期时间转换成xx秒前.xx分钟前.xx小时前...) package com.liuzy.javaopen.entity; import java.text.ParseExce ...

  4. java处理日期时间 相加减

    参考:http://alexfc.iteye.com/blog/363185 JAVA处理日期时间常用方法: 1.java.util.Calendar  Calendar 类是一个抽象类,它为特定瞬间 ...

  5. java获取日期/时间

    获取年月日.小时分钟秒 public class DateTimeTest {public static void main(String[] args) {Calendar cal = Calend ...

  6. mongo java 日期,Java 8日期/时间(JSR-310)类型与Spring Data MongoDB的映射

    我有Java 8日期/时间字段的简单文档 @Document public class Token { private Instant createdAt; ... } 我希望坚持使用Spring D ...

  7. es6 日期字符串转日期_Pandas核心能力9:日期时间转换、提取、筛选

    Pandas核心能力9:日期时间转换.提取.筛选 In [1]: import numpy as npimport pandas as pddatetime_index = pd.date_range ...

  8. 项目部署到服务器上页面上的时间与数据库相差8小时

    更多详细请关注博客原文:盐鱼律己-项目部署到服务器上页面上的时间与数据库相差8小时 问题描述 项目在本地运行时页面上的时间与数据库中的相同,但是部署到服务器上后页面上显示的时间比数据库中早8个小时. ...

  9. java getday_java日期时间处理小结

    Calendar是一个抽象类----专门获取一个时间点的DAY,MONTH,YEAR,一年中的第几天,星期几,一个月中的第几天等等 Calendar rightNow = Calendar.getIn ...

最新文章

  1. Shiro 那点事儿
  2. C++面试笔记(2)
  3. java 反射模式_java 设计模式——反射机制的应用
  4. HTML5+PhoneGap相机拍照
  5. Java中的数据库架构导航
  6. LR通过SiteScope监控mysql
  7. [hackinglab][CTF][上传关][2020] hackinglab 上传关 writeup
  8. java 泛型 `List<Object>` 和`List<String>`
  9. web逻辑思维题目_经典的逻辑思维训练题
  10. 3、NDK下载、安装
  11. Excel高级应用专题-数组公式
  12. Vue.js 菜鸟教程 思维导图
  13. 分割线与边框嵌入文字
  14. linux uwsgi 非root,只能以root身份运行uwsgi
  15. 服务器重装系统c盘过大,C盘满了,不想重装系统怎么办?
  16. 22、T5L 迪文屏 C51开发之Hello World例程
  17. 实验4 FIR数字滤波器设计及软件实现
  18. linux电脑系统桌面文件怎么恢复出厂设置密码,树莓派如何恢复LXPanel面板默认设置-恢复出厂设置英文...
  19. linux中将文本中的单词换掉的指令_干货:Linux常用命令全称及讲解
  20. cortex m3/m4处理器的复位设计

热门文章

  1. 转转二手交易网成为更多人选择的交易平台
  2. 芯片界总说的7nm到底有多细
  3. 缩略图Thumbnails
  4. 20210706多校联考
  5. LiteOS移植到STM32F103系列单片机,非常简单
  6. 【老生谈算法】matlab实现单相桥式全控整流电路仿真——全控整流
  7. linux更新应用的命令,linux常用的软件更新命令,自己操作不求人!
  8. 什么是IPv6?它有什么特别之处?
  9. 达梦数据库(DM)的安装教程分享
  10. XNA游戏开发之字符篇