Java 字符串日期到 xmlgregoriancalendar 的转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20970088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
String date to xmlgregoriancalendar conversion
提问by JavaStudent
I have written this function :
我写了这个函数:
public static XMLGregorianCalendar getXMLGregorianCalendar(String date) throws OmniException{
XMLGregorianCalendar xmlCalender=null;
GregorianCalendar calender = new GregorianCalendar();
calender.setTime(Util.stringToJavaDate(date));
xmlCalender = DatatypeFactory.newInstance().newXMLGregorianCalendar(calender);
return xmlCalender;
}
public static Date stringToJavaDate(String sDate) throws OmniException{
Date date=null;
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).parse(sDate);
return date;
}
When i am passing date as "2014-01-07"
am getting output date as 2014-01-06T18:30:00:000Z
where i am going wrong ?
also what to do if I want to get only 2014-01-06T18:30:00
and 2014-01-06T18:30:00Z
Any help is appreciated
当我通过日期作为"2014-01-07"
获取输出日期作为2014-01-06T18:30:00:000Z
我出错的地方时?还做什么,如果我想只得到2014-01-06T18:30:00
和2014-01-06T18:30:00Z
任何帮助表示赞赏
采纳答案by JavaStudent
Found the solution as below.... posting it as it could help somebody else too :)
找到如下解决方案....发布它,因为它也可以帮助其他人:)
DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = format.parse("2014-04-24 11:15:00");
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
XMLGregorianCalendar xmlGregCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
System.out.println(xmlGregCal);
Output:
输出:
2014-04-24T11:15:00.000+02:00
2014-04-24T11:15:00.000+02:00
回答by regulus001
GregorianCalendar c = GregorianCalendar.from((LocalDate.parse("2016-06-22")).atStartOfDay(ZoneId.systemDefault()));
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
回答by gil.fernandes
For me the most elegant solution is this one:
对我来说,最优雅的解决方案是这个:
XMLGregorianCalendar result = DatatypeFactory.newInstance()
.newXMLGregorianCalendar("2014-01-07");
Using Java 8.
使用 Java 8。
Extended example:
扩展示例:
XMLGregorianCalendar result = DatatypeFactory.newInstance()
.newXMLGregorianCalendar("2014-01-07");
System.out.println(result.getDay());
System.out.println(result.getMonth());
System.out.println(result.getYear());
This prints out:
这打印出来:
7
1
2014
回答by Basil Bourque
tl;dr
tl;博士
- Use modern java.timeclasses as much as possible, rather than the terrible legacy classes.
- Always specify your desired/expected time zone or offset-from-UTC rather than rely implicitly on JVM's current default.
- 尽可能多地使用现代java.time类,而不是可怕的遗留类。
- 始终指定您想要/期望的时区或从 UTC 的偏移量,而不是隐式依赖 JVM 的当前默认值。
Example code (without exception-handling):
示例代码(无异常处理):
XMLGregorianCalendar xgc =
DatatypeFactory // Data-type converter.
.newInstance() // Instantiate a converter object.
.newXMLGregorianCalendar( // Converter going from `GregorianCalendar` to `XMLGregorianCalendar`.
GregorianCalendar.from( // Convert from modern `ZonedDateTime` class to legacy `GregorianCalendar` class.
LocalDate // Modern class for representing a date-only, without time-of-day and without time zone.
.parse( "2014-01-07" ) // Parsing strings in standard ISO 8601 format is handled by default, with no need for custom formatting pattern.
.atStartOfDay( ZoneOffset.UTC ) // Determine the first moment of the day as seen in UTC. Returns a `ZonedDateTime` object.
) // Returns a `GregorianCalendar` object.
) // Returns a `XMLGregorianCalendar` object.
;
Parsing date-only input string into an object of XMLGregorianCalendar
class
将仅限日期的输入字符串解析为XMLGregorianCalendar
类的对象
Avoid the terrible legacy date-time classes whenever possible, such as XMLGregorianCalendar
, GregorianCalendar
, Calendar
, and Date
. Use only modern java.timeclasses.
避免可怕的遗产日期时类只要有可能,例如XMLGregorianCalendar
,GregorianCalendar
,Calendar
,和Date
。仅使用现代java.time类。
When presented with a string such as "2014-01-07"
, parse as a LocalDate
.
当出现诸如 之类的字符串时"2014-01-07"
,解析为LocalDate
.
LocalDate.parse( "2014-01-07" )
To get a date with time-of-day, assuming you want the first moment of the day, specify a time zone. Let java.timedetermine the first moment of the day, as it is not always 00:00:00.0 in some zones on some dates.
要获取包含时间的日期,假设您想要一天中的第一个时刻,请指定一个时区。让java.time确定一天中的第一个时刻,因为在某些日期的某些区域中,它并不总是 00:00:00.0。
LocalDate.parse( "2014-01-07" )
.atStartOfDay( ZoneId.of( "America/Montreal" ) )
This returns a ZonedDateTime
object.
这将返回一个ZonedDateTime
对象。
ZonedDateTime zdt =
LocalDate
.parse( "2014-01-07" )
.atStartOfDay( ZoneId.of( "America/Montreal" ) )
;
zdt.toString() = 2014-01-07T00:00-05:00[America/Montreal]
zdt.toString() = 2014-01-07T00:00-05:00[美国/蒙特利尔]
But apparently, you want the start-of-day as seen in UTC (an offset of zero hours-minutes-seconds). So we specify ZoneOffset.UTC
constant as our ZoneId
argument.
但显然,您想要在 UTC 中看到的一天开始(零时分秒的偏移量)。所以我们指定ZoneOffset.UTC
常量作为我们的ZoneId
参数。
ZonedDateTime zdt =
LocalDate
.parse( "2014-01-07" )
.atStartOfDay( ZoneOffset.UTC )
;
zdt.toString() = 2014-01-07T00:00Z
zdt.toString() = 2014-01-07T00:00Z
The Z
on the end means UTC (an offset of zero), and is pronounced “Zulu”.
该Z
对端装置UTC(零偏移量),并且被读作“祖鲁”。
If you must work with legacy classes, convert to GregorianCalendar
, a subclass of Calendar
.
如果您必须使用遗留类,请转换为GregorianCalendar
, 的子类Calendar
。
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;
gc.toString() = java.util.GregorianCalendar[time=1389052800000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2014,MONTH=0,WEEK_OF_YEAR=2,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=7,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=0,DST_OFFSET=0]
gc.toString() = java.util.GregorianCalendar[time=1389052800000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings= 0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2014,MONTH=0,WEEK_OF_YEAR=2,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=7 ,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=0,DST_OFFSET=0]
Apparently, you really need an object of the legacy class XMLGregorianCalendar
. If the calling code cannot be updated to use java.time, convert.
显然,您确实需要一个遗留类的对象XMLGregorianCalendar
。如果调用代码无法更新为使用java.time,请转换。
XMLGregorianCalendar xgc =
DatatypeFactory
.newInstance()
.newXMLGregorianCalendar( gc )
;
Actually, that code requires a try-catch.
实际上,该代码需要 try-catch。
try
{
XMLGregorianCalendar xgc =
DatatypeFactory
.newInstance()
.newXMLGregorianCalendar( gc );
}
catch ( DatatypeConfigurationException e )
{
e.printStackTrace();
}
xgc = 2014-01-07T00:00:00.000Z
xgc = 2014-01-07T00:00:00.000Z
Putting that all together, with appropriate exception-handling.
将所有这些放在一起,并进行适当的异常处理。
// Given an input string such as "2014-01-07", return a `XMLGregorianCalendar` object
// representing first moment of the day on that date as seen in UTC.
static public XMLGregorianCalendar getXMLGregorianCalendar ( String input )
{
Objects.requireNonNull( input );
if( input.isBlank() ) { throw new IllegalArgumentException( "Received empty/blank input string for date argument. Message # 11818896-7412-49ba-8f8f-9b3053690c5d." ) ; }
XMLGregorianCalendar xgc = null;
ZonedDateTime zdt = null;
try
{
zdt =
LocalDate
.parse( input )
.atStartOfDay( ZoneOffset.UTC );
}
catch ( DateTimeParseException e )
{
throw new IllegalArgumentException( "Faulty input string for date does not comply with standard ISO 8601 format. Message # 568db0ef-d6bf-41c9-8228-cc3516558e68." );
}
GregorianCalendar gc = GregorianCalendar.from( zdt );
try
{
xgc =
DatatypeFactory
.newInstance()
.newXMLGregorianCalendar( gc );
}
catch ( DatatypeConfigurationException e )
{
e.printStackTrace();
}
Objects.requireNonNull( xgc );
return xgc ;
}
Usage.
用法。
String input = "2014-01-07";
XMLGregorianCalendar xgc = App.getXMLGregorianCalendar( input );
Dump to console.
转储到控制台。
System.out.println( "xgc = " + xgc );
xgc = 2014-01-07T00:00:00.000Z
xgc = 2014-01-07T00:00:00.000Z
Modern date-time classes versus legacy
现代日期时间类与遗留类
Date-time != String
日期时间 != 字符串
Do not conflate a date-time value with its textual representation. We parse strings to get a date-time object, and we ask the date-time object to generate a string to represent its value. The date-time object has no ‘format', only strings have a format.
不要将日期时间值与其文本表示混为一谈。我们解析字符串以获取日期时间对象,然后我们要求日期时间对象生成一个字符串来表示其值。日期时间对象没有“格式”,只有字符串才有格式。
So shift your thinking into two separate modes: model and presentation. Determine the date-value you have in mind, applying appropriate time zone, as the model. When you need to display that value, generate a string in a particular format as expected by the user.
因此,将您的思维转变为两种不同的模式:模型和演示。确定您想到的日期值,应用适当的时区作为模型。当您需要显示该值时,按照用户的预期生成特定格式的字符串。
Avoid legacy date-time classes
避免遗留的日期时间类
The Question and other Answers all use old troublesome date-time classes now supplanted by the java.time classes.
问题和其他答案都使用旧的麻烦的日期时间类,现在已被 java.time 类取代。
ISO 8601
ISO 8601
Your input string "2014-01-07"
is in standard ISO 8601format.
您的输入字符串"2014-01-07"
采用标准ISO 8601格式。
The T
in the middle separates date portion from time portion.
在T
从时间部分在中间中隔离日期部分。
The Z
on the end is short for Zulu and means UTC.
在Z
上月底是短期的祖鲁语和手段UTC。
Fortunately, the java.time classes use the ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
幸运的是,java.time 类在解析/生成字符串时默认使用 ISO 8601 格式。所以不需要指定格式模式。
LocalDate
LocalDate
The LocalDate
class represents a date-only value without time-of-day and without time zone.
该LocalDate
级表示没有时间一天和不同时区的日期,唯一的价值。
LocalDate ld = LocalDate.parse( "2014-01-07" ) ;
ld.toString(): 2014-01-07
ld.toString(): 2014-01-07
Start of day ZonedDateTime
一天的开始 ZonedDateTime
If you want to see the first moment of that day, specify a ZoneId
time zone to get a moment on the timeline, a ZonedDateTime
. The time zone is crucial because the date varies around the globe by zone. A few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
如果您想查看当天的第一个时刻,请指定一个ZoneId
时区以获取时间轴上的时刻,一个ZonedDateTime
. 时区至关重要,因为日期在全球各地因地区而异。午夜过后几分钟在巴黎法国是新的一天,而在魁北克蒙特利尔仍然是“昨天”。
Never assume the day begins at 00:00:00. Anomalies such as Daylight Saving Time (DST) means the day may begin at another time-of-day such as 01:00:00. Let java.time determine the first moment.
永远不要假设一天从 00:00:00 开始。夏令时 (DST) 等异常意味着一天可能会在一天中的另一个时间开始,例如 01:00:00。让 java.time 确定第一时刻。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
zdt.toString(): 2014-01-07T00:00:00Z
zdt.toString(): 2014-01-07T00:00:00Z
For your desired format, generate a string using the predefined formatter DateTimeFormatter.ISO_LOCAL_DATE_TIME
and then replace the T
in the middle with a SPACE.
对于您想要的格式,使用预定义的格式化程序生成一个字符串DateTimeFormatter.ISO_LOCAL_DATE_TIME
,然后用T
空格替换中间的。
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " ) ;
2014-01-07 00:00:00
2014-01-07 00:00:00
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use ThreeTenABP….
- Java SE 8、Java SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。