简体   繁体   English

在 Java 中将字符串转换为日历对象

[英]Convert String to Calendar Object in Java

I am new to Java, usually work with PHP.我是 Java 新手,通常使用 PHP。

I am trying to convert this string:我正在尝试转换此字符串:

Mon Mar 14 16:02:37 GMT 2011格林威治标准时间 2011 年 3 月 14 日星期一 16:02:37

Into a Calendar Object so that I can easily pull the Year and Month like this:进入日历对象,以便我可以轻松地拉出年和月,如下所示:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

Would it be a bad idea to parse it manually?手动解析它是不是一个坏主意? Using a substring method?使用子串方法?

Any advice would help thanks!任何建议都会有所帮助谢谢!

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

note: set Locale according to your environment/requirement注意:根据您的环境/要求设置Locale


See Also也可以看看

tl;dr tl;博士

The modern approach uses the java.time classes.现代方法使用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()

2011-03 2011-03

Avoid legacy date-time classes避免遗留的日期时间类

The modern way is with java.time classes.现代方法是使用 java.time 类。 The old date-time classes such as Calendar have proven to be poorly-designed, confusing, and troublesome.旧的日期时间类(例如Calendar已被证明设计不佳、混乱且麻烦。

Define a custom formatter to match your string input.定义自定义格式化程序以匹配您的字符串输入。

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

Parse as a ZonedDateTime .解析为ZonedDateTime

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

You are interested in the year and month.您对年份和月份感兴趣。 The java.time classes include YearMonth class for that purpose.为此,java.time 类包括YearMonth类。

YearMonth ym = YearMonth.from( zdt );

You can interrogate for the year and month numbers if needed.如果需要,您可以查询年份和月份数字。

int year = ym.getYear();
int month = ym.getMonthValue();

But the toString method generates a string in standard ISO 8601 format.但是toString方法生成标准ISO 8601格式的字符串。

String output = ym.toString();

Put this all together.把这一切放在一起。

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();

Dump to console.转储到控制台。

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

input: Mon Mar 14 16:02:37 GMT 2011输入:格林威治标准时间 2011 年 3 月 14 日星期一 16:02:37

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

ym: 2011-03 ym: 2011-03

Live code实时代码

See this code running in IdeOne.com .请参阅在 IdeOne.com 中运行的此代码

Conversion转换

If you must have a Calendar object, you can convert to a GregorianCalendar using new methods added to the old classes.如果您必须有一个Calendar对象,您可以使用添加到旧类的新方法转换为GregorianCalendar

GregorianCalendar gc = GregorianCalendar.from( zdt );

About java.time关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于 Java 8 及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和SimpleDateFormat

To learn more, see the Oracle Tutorial .要了解更多信息,请参阅Oracle 教程 And search Stack Overflow for many examples and explanations.并在 Stack Overflow 上搜索许多示例和解释。 Specification is JSR 310 .规范是JSR 310

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.现在处于维护模式Joda-Time项目建议迁移到java.time类。

You may exchange java.time objects directly with your database.您可以直接与您的数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later.使用符合JDBC 4.2或更高版本的JDBC 驱动程序 No need for strings, no need for java.sql.* classes.不需要字符串,不需要java.sql.*类。 Hibernate 5 & JPA 2.2 support java.time . Hibernate 5 & JPA 2.2 支持java.time

Where to obtain the java.time classes?从哪里获得 java.time 类?

Well, I think it would be a bad idea to replicate the code which is already present in classes like SimpleDateFormat .好吧,我认为复制已经存在于SimpleDateFormat类的类中的代码是一个坏主意。

On the other hand, personally I'd suggest avoiding Calendar and Date entirely if you can, and using Joda Time instead, as a far better designed date and time API.另一方面,我个人建议如果可以的话完全避免使用CalendarDate ,而使用Joda Time作为设计得更好的日期和时间 API。 For example, you need to be aware that SimpleDateFormat is not thread-safe, so you either need thread-locals, synchronization, or a new instance each time you use it.例如,您需要注意SimpleDateFormat不是线程安全的,因此您每次使用它时都需要线程局部变量、同步或新实例。 Joda parsers and formatters are thread-safe. Joda 解析器和格式化器线程安全的。

No new Calendar needs to be created, SimpleDateFormat already uses a Calendar underneath.不需要创建新的 Calendar,SimpleDateFormat 已经在下面使用了 Calendar。

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();

(I can't comment yet, that's why I created a new answer) (我还不能发表评论,这就是我创建新答案的原因)

SimpleDateFormat is great, just note that HH is different from hh when working with hours. SimpleDateFormat很棒,请注意HHhh在使用小时时不同。 HH will return 24 hour based hours and hh will return 12 hour based hours. HH将返回基于 24 小时的小时数,而 hh 将返回基于 12 小时的小时数。

For example, the following will return 12 hour time:例如,以下将返回 12 小时时间:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

While this will return 24 hour time:虽然这将返回 24 小时时间:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

Parse a time with timezone, Z in pattern is for time zone用时区解析时间,模式中的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();
}

Output: it will return the UTC time输出:它将返回UTC时间

1508899140000

在此处输入图片说明

If we don't set the time zone in pattern like yyyy-MM-dd'T'HH:mm:ss .如果我们没有像yyyy-MM-dd'T'HH:mm:ss这样的模式设置时区。 SimpleDateFormat will use the time zone which have set in Setting SimpleDateFormat将使用设置中Setting的时区

Yes it would be bad practice to parse it yourself.是的,自己解析它是不好的做法。 Take a look at SimpleDateFormat , it will turn the String into a Date and you can set the Date into a Calendar instance.看看SimpleDateFormat ,它会将 String 转换为 Date ,您可以将 Date 设置为 Calendar 实例。

Simple method:简单方法:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
    String DEFAULT_LOCALE_NAME = "pt";
    String DEFAULT_COUNTRY = "BR";
    Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    Date d = format.parse(date);
    Calendar c = getCalendar();
    c.setTime(d);
    return c;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM