我需要在C#中使用的那种格式
DateTime.Now.ToString("o")
。 DateTime.Now.ToString("o")
的示例返回日期为
2016-03-10T11:24:59.7862749 + 04:00
然后在 sql中插入
2016-03-10 11:24:59.786
我试图从java插入相同的日期格式。我用的是:
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
并返回此
2016-03-10T07:29 + 0000
由于这种格式,它会出错。如何将格式更改为我想要的格式?
答案 0 :(得分:6)
对于Java 7,您可以使用:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
System.out.println(df.format(new Date()));
这使用了模式符号XXX,它也会在偏移内打印冒号。但是,对于Java-6,不提供此功能。并且精度始终限制在毫秒级。
对于Java-8,您还可以使用:
DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
System.out.println(OffsetDateTime.now().format(dtf)); // 2016-03-10T08:46:44.849+01:00
如果有这样的时钟(从Java-9开始),这将实现纳秒精度。
对于Java-6 ,要么应用基于SimpleDateFormat
的hack,要么使用外部库:
// Java-6 (SimpleDateFormat)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String text = sdf.format(new Date());
text = text.substring(0, text.length() - 2) + ":" + text.substring(text.length() - 2);
System.out.println(text);
// Joda-Time
DateTime now = DateTime.now();
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").print(now));
// Time4J
Moment now = SystemClock.currentMoment();
System.out.println(Iso8601Format.EXTENDED_DATE_TIME_OFFSET.withStdTimezone().format(now));
答案 1 :(得分:3)
Answer by Meno Hochschild是正确的。我只是添加一些注释和一些特定于SQL的代码。
旧的日期时间类java.util.Date/.Calendar& java.text.SimpleDateFormat,设计糟糕,令人困惑,麻烦。避免它们。
旧的条款已经被Java 8及更高版本中内置的java.time框架所取代。
要在Java 8之前使用,请查看ThreeTen-Backport项目。
java.time类具有纳秒分辨率。因此,由于旧类使用的毫秒级分辨率,2016-03-10T11:24:59.7862749+04:00
被截断为2016-03-10 11:24:59.786
,因此您不会遇到数据丢失问题。
由于遗留问题,获取Java 8中的当前时刻仅限于毫秒,小数点后三位数。 Java 9将以纳秒为单位获得当前时刻,最多可达十位小数九位数(假设您的计算机的硬件时钟可以提供如此精细的分辨率)。
ISO 8601标准定义了日期时间值的合理文本格式。例如,2016-03-09T23:24:33Z
或2016-03-09T22:24:33-01:00
。 java.time类默认使用这些,因此不需要定义解析模式。
Instant
是UTC时间轴上的一个时刻。
Instant instant = Instant.now();
调用Instant::toString
以标准格式生成字符串。
String output = instant.toString();
2016-03-09T23:24:33.123Z
OffsetDateTime
应用ZoneOffset
获取OffsetDateTime
。
ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes( -5 , 30 );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
如果您知道完整时区而非offset-from-UTC,请应用ZoneId
获取ZonedDateTime
。
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ); // "Europe/Paris", "America/Montreal", etc.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
java.sql.Timestamp
希望JDBC驱动程序将更新为直接使用java.time类型。在此之前,我们将转换为java.sql类型,以便在数据库中传输数据。
如上所述,java.time可以处理纳秒。 java.sql.Timestamp
也是如此。但是您的数据库可能没有。某些数据库限制为整秒,毫秒或微秒。当数据通过JDBC传递到数据库时,数据库可能会被截断。
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
......走向另一个方向......
Instant instant = ts.toInstant();
请注意,根据定义,Instant
始终为UTC。因此,无需在问题结束时执行尝试的那种代码。
使用日期时,应尽可能减少字符串的使用。最大限度地使用有用的日期时间类/对象,即java.time类。不要将字符串视为日期时间值 - 它们是日期时间值的文本表示。
不要将日期时间值作为字符串插入/从数据库中检索。使用java.sql.Timestamp
和java.sql.Date
等java.sql对象。使用PreparedStatement
和"设置/获取" setTimestamp
/ getTimestamp
等方法。在数据库中虚拟always define your columns为TIMESTAMP WITH TIME ZONE
而不是“没有时区”。
从数据库获取数据时,请使用java.sql类型。但是尽快转换为java.time类型。 java.sql类型是一个混乱,一个脏的黑客,应该只用于数据传输而不是业务逻辑。
通常最好在业务逻辑,数据存储,数据交换,API调用等中使用UTC。仅在用户需要或数据接收器要求时调整为时区。
答案 2 :(得分:2)
使用此格式" yyyy-MM-dd' H&H:mm:ss.SSSZ"
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
System.out.println(df.format(new Date()));