在Java中将String转换为Calendar对象

Dou*_*eux 163 java datetime calendar date simpledateformat

我是Java新手,通常使用PHP.

我想转换这个字符串:

2011年3月14日星期四16:02:37 GMT

进入一个Calendar对象,这样我就可以像这样轻松地拉出Year和Month:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);
Run Code Online (Sandbox Code Playgroud)

手动解析是不是一个坏主意?使用子字符串方法?

任何建议都会有所帮助!

Jig*_*shi 375

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Run Code Online (Sandbox Code Playgroud)

注意:Locale根据您的环境/要求进行设置


也可以看看

  • 请注意,这会丢失时区信息.Calendar对象将具有系统默认TimeZone而不是已解析的TimeZone. (6认同)

Bas*_*que 16

TL;博士

现代方法使用java.time类.

YearMonth.from(
    ZonedDateTime.parse( 
        "Mon Mar 14 16:02:37 GMT 2011" , 
        DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
     )
).toString()
Run Code Online (Sandbox Code Playgroud)

2011-03

避免遗留日期时间类

现代方法是使用java.time类.旧的日期时间类Calendar已被证明设计不当,令人困惑和麻烦.

定义自定义格式化程序以匹配您的字符串输入.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
Run Code Online (Sandbox Code Playgroud)

解析为ZonedDateTime.

ZonedDateTime zdt = ZonedDateTime.parse( input , f );
Run Code Online (Sandbox Code Playgroud)

您对年份和月份感兴趣.java.time类包含YearMonth用于此目的的类.

YearMonth ym = YearMonth.from( zdt );
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以查询年份和月份数字.

int year = ym.getYear();
int month = ym.getMonthValue();
Run Code Online (Sandbox Code Playgroud)

但该toString方法生成标准ISO 8601格式的字符串.

String output = ym.toString();
Run Code Online (Sandbox Code Playgroud)

把这一切都放在一起.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();
Run Code Online (Sandbox Code Playgroud)

转储到控制台.

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );
Run Code Online (Sandbox Code Playgroud)

输入:2011年3月14日16:02:37 GMT 2011

zdt:2011-03-14T16:02:37Z [GMT]

是的:2011-03

实时代码

请参阅IdeOne.com中运行的此代码.

转变

如果必须Calendar对象,则可以转换为GregorianCalendar使用添加到旧类的新方法.

GregorianCalendar gc = GregorianCalendar.from( zdt );
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.


Jon*_*eet 14

好吧,我认为复制已经存在于类中的代码是一个坏主意SimpleDateFormat.

另一方面,我个人建议尽可能地避免CalendarDate使用Joda Time作为更好的日期和时间API.例如,你需要知道,SimpleDateFormat不是线程安全的,所以你要么需要线程本地人,同步,或一个新实例每次使用它的时候.Joda解析器和格式化程序线程安全的.

  • @Scolytus:最高(和接受)的答案有332票,而在这一票上有10票.我想如果你现在围绕着每一个有着更好解决方案的7岁以上的答案,那么你将会失控...(我同意巴兹尔的回答很好,而且我已经投了赞成票.) (2认同)

GoG*_*ris 9

无需创建新日历,SimpleDateFormat已在下方使用日历.

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();
Run Code Online (Sandbox Code Playgroud)

(我还不能发表评论,这就是我创建新答案的原因)


小智 5

SimpleDateFormat非常棒,请注意HHhh工作时间不同.HH将返回24小时工作小时,并将返回12小时工作小时.

例如,以下将返回12小时时间:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");
Run Code Online (Sandbox Code Playgroud)

虽然这将返回24小时时间:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Run Code Online (Sandbox Code Playgroud)


Pha*_*inh 5

用时区解析时间,Z模式是时区

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(aTime));
    Log.i(TAG, "time = " + cal.getTimeInMillis()); 
} catch (ParseException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

输出:它将返回UTC时间

1508899140000
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如果我们不以类似的模式设置时区yyyy-MM-dd'T'HH:mm:ssSimpleDateFormat将使用已设置的时区Setting