将年月日字符串通过Calendar转成Date后月份被加一问题

一、问题描述

简单描述下问题:数据库有一个开始时间字段`start_time` varchar(20) NOT NULL DEFAULT '' COMMENT '开始日',存储形如"2022-04-25"年月日的字符串,业务中需要将其转换为指定小时的形如"2022-04-25 07:00:00.0"的Date对象。我是通过Calendar类来处理实现的,代码如下:

    public static Date formatStartDate(String dateStr, int startHour) {
        String[] split = date.split("-");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, Integer.valueOf(split[0]));
        calendar.set(Calendar.MONTH, Integer.valueOf(split[1]));
        calendar.set(Calendar.DATE, Integer.valueOf(split[2]));
        calendar.set(Calendar.HOUR_OF_DAY, startHour);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
    
    public static void main(String[] args) {
        Date date = formatStartDate("2022-04-25", 7);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = format.format(date);
        System.out.println("dateStr:" + dateStr);
    }

运行结果如下:

从运行结果可以看到,月份被加了一个月,4月变成了5月。

二、问题分析

查看Calendar源码可以看到,其关于月份的定义如下:

    /**
     * Value of the {@link #MONTH} field indicating the
     * first month of the year in the Gregorian and Julian calendars.
     */
    public final static int JANUARY = 0;

    /**
     * Value of the {@link #MONTH} field indicating the
     * second month of the year in the Gregorian and Julian calendars.
     */
    public final static int FEBRUARY = 1;

    /**
     * Value of the {@link #MONTH} field indicating the
     * third month of the year in the Gregorian and Julian calendars.
     */
    public final static int MARCH = 2;

    /**
     * Value of the {@link #MONTH} field indicating the
     * fourth month of the year in the Gregorian and Julian calendars.
     */
    public final static int APRIL = 3;

    /**
     * Value of the {@link #MONTH} field indicating the
     * fifth month of the year in the Gregorian and Julian calendars.
     */
    public final static int MAY = 4;

    /**
     * Value of the {@link #MONTH} field indicating the
     * sixth month of the year in the Gregorian and Julian calendars.
     */
    public final static int JUNE = 5;

    /**
     * Value of the {@link #MONTH} field indicating the
     * seventh month of the year in the Gregorian and Julian calendars.
     */
    public final static int JULY = 6;

    /**
     * Value of the {@link #MONTH} field indicating the
     * eighth month of the year in the Gregorian and Julian calendars.
     */
    public final static int AUGUST = 7;

    /**
     * Value of the {@link #MONTH} field indicating the
     * ninth month of the year in the Gregorian and Julian calendars.
     */
    public final static int SEPTEMBER = 8;

    /**
     * Value of the {@link #MONTH} field indicating the
     * tenth month of the year in the Gregorian and Julian calendars.
     */
    public final static int OCTOBER = 9;

    /**
     * Value of the {@link #MONTH} field indicating the
     * eleventh month of the year in the Gregorian and Julian calendars.
     */
    public final static int NOVEMBER = 10;

    /**
     * Value of the {@link #MONTH} field indicating the
     * twelfth month of the year in the Gregorian and Julian calendars.
     */
    public final static int DECEMBER = 11;

通过上面可以看到,4代表的是May(五月),所以通过上面代码中 calendar.set(Calendar.MONTH, Integer.valueOf(split[1]));设置月份的时候本质上是 calendar.set(Calendar.MONTH, 4);,即月份设置的是五月,故而出现这个问题。

三、解决方式

方式1

既然月份是从0-11,那么在设置月份的时候减1即可:

// 将上面的值减1作为月份
calendar.set(Calendar.MONTH, Integer.valueOf(split[1]) - 1);

 方式2

也可以不使用Calendar类,而是使用如下方式,代码如下:

    public static Date formatStartDate(String dateStr, int startHour) throws Exception{
        Date date = DateUtils.parseDate(dateStr, "yyyy-MM-dd");
        return DateUtils.setHours(date, startHour);
    }

四、补充

除了月份外,Calendar类中也定义的一些关于星期的常量,如下:

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Sunday.
     */
    public final static int SUNDAY = 1;

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Monday.
     */
    public final static int MONDAY = 2;

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Tuesday.
     */
    public final static int TUESDAY = 3;

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Wednesday.
     */
    public final static int WEDNESDAY = 4;

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Thursday.
     */
    public final static int THURSDAY = 5;

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Friday.
     */
    public final static int FRIDAY = 6;

    /**
     * Value of the {@link #DAY_OF_WEEK} field indicating
     * Saturday.
     */
    public final static int SATURDAY = 7;

如果想通过calendar.get(Calendar.DAY_OF_WEEK);获取指定日期是星期几也需要特别处理。

比如想获取2022年4月25日是星期几,通过这种方式获取到的将是2,实际上这天是星期一。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以使用Java中的SimpleDateFormat类和Calendar类来实现英文字符串日期转换为中文字符串年月日。具体代码如下: ```java import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; public class EnglishToChineseDateConverter { public static void main(String[] args) throws Exception { String dateString = "2022-01-01"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); Date date = sdf.parse(dateString); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); String year = String.valueOf(calendar.get(Calendar.YEAR)); String month = String.valueOf(calendar.get(Calendar.MONTH) + 1); String day = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)); String chineseDate = year + "年" + month + "月" + day + "日"; System.out.println("中文日期:" + chineseDate); } } ``` 在这个例子中,我们首先定义了一个字符串类型的日期`dateString`,它表示英文格式的日期。然后,我们使用`SimpleDateFormat`类将其解析为`Date`类型的日期对象。 接着,我们创建了一个`Calendar`对象,并将其设置为解析后的日期对象。通过`Calendar`对象,我们可以获取年、月、日等日期信息,并将其转换为字符串类型的中文日期。 最后,我们将年、月、日拼接成中文日期字符串,并将其打印到控制台上。 需要注意的是,在`SimpleDateFormat`构造函数中,我们使用了`Locale.ENGLISH`参数来指定解析的日期格式为英文。如果想要解析其他语言的日期,可以将`Locale.ENGLISH`替换为相应的语言代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffylv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值