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

问题描述 投票:0回答:9

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

我正在尝试转换这个字符串:

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

进入日历对象,以便我可以轻松地拉出年份和月份,如下所示:

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

手动解析它是一个坏主意吗?使用子串方法?

任何建议都会有所帮助,谢谢!

java date datetime calendar simpledateformat
9个回答
457
投票
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

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

Locale


另请参阅


26
投票

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

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

解析为

ZonedDateTime

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

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

YearMonth
类。

YearMonth ym = YearMonth.from( zdt );

如果需要,您可以询问年份和月份数字。

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

但是

toString
方法会生成标准 ISO 8601 格式的字符串。

String output = ym.toString();

把这些放在一起。

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

转储到控制台。

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

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

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

ym:2011-03

实时代码

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

转换

如果您必须有一个

Calendar
对象,您可以使用添加到旧类中的新方法转换为
GregorianCalendar

GregorianCalendar gc = GregorianCalendar.from( zdt );

关于 java.time

java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如

java.util.Date
Calendar
SimpleDateFormat

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要

java.sql.*
类。 Hibernate 5 和 JPA 2.2 支持 java.time.

从哪里获取java.time类?


14
投票

好吧,我认为复制像

SimpleDateFormat
这样的类中已经存在的代码是一个坏主意。

另一方面,我个人建议如果可以的话完全避免使用

Calendar
Date
,而使用 Joda Time 来代替,作为设计得更好的日期和时间 API。例如,您需要注意
SimpleDateFormat
not 线程安全的,因此每次使用它时,您要么需要线程局部变量、同步,要么需要一个新实例。 Joda 解析器和格式化程序线程安全的。


10
投票

不需要创建新的日历,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();

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


6
投票

SimpleDateFormat
很棒,请注意,在处理小时数时,
HH
hh
不同。
HH
将返回基于 24 小时的时间,hh 将返回基于 12 小时的时间。

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

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

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

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

6
投票

用时区解析时间,模式中的

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

输出:它将返回UTC时间

1508899140000

enter image description here

如果我们不按照

yyyy-MM-dd'T'HH:mm:ss
的模式设置时区。
SimpleDateFormat
将使用
Setting

设置的时区

3
投票

是的,自己解析它是不好的做法。 看一下SimpleDateFormat,它会将字符串转换为日期,你可以将日期设置为日历实例。


1
投票

简单方法:

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;
}

0
投票

我认为这是最有效的方法。

/**
 * Customized Date and Time Formats
 * Pattern                          Output
 * dd.MM.yy                         30.06.09
 * yyyy.MM.dd G 'at' hh:mm:ss z     2009.06.30 AD at 08:29:36 PDT
 * EEE, MMM d, ''yy Tue,            Jun 30, '09
 * h:mm a                           8:29 PM
 * H:mm                             8:29
 * H:mm:ss:SSS                      8:28:36:249
 * K:mm a,z                         8:29 AM,PDT
 * yyyy.MMMMM.dd GGG hh:mm aaa      2009.June.30 AD 08:29 AM
 */


public static LocalDateTime toLocalDateTime(long timeInMs){
    return Instant.ofEpochMilli(timeInMs).atZone(ZoneId.systemDefault()).toLocalDateTime();
}

public static LocalDateTime parseTimeNumeric(String time){
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat formatter = new SimpleDateFormat("dd" + "." + "MM" + "." + "yy" + " " + "HH" + ":" + "mm" + ":" + "ss");
    try {
        calendar.setTime(formatter.parse(time));
    } catch (ParseException e) {
        return null;
    }
    return toLocalDateTime(calendar.getTimeInMillis());
}

示例

    LocalDateTime localDateTime = parseTimeNumeric("time format");

    localDateTime.getYear();
    localDateTime.getMonthValue();
    localDateTime.getDayOfMonth();
    localDateTime.getHour();
    localDateTime.getMinute();
    localDateTime.getSecond();
© www.soinside.com 2019 - 2024. All rights reserved.