Java simpledateformat.parse输入错误的年份

时间:2018-11-15 09:51:15

标签: java date simpledateformat

我正在尝试从字符串中解析日期,然后将其保存到数据库,但是有时有时在检查数据库时年份值错误。

private SimpleDateFormat simpleDateFormatTimestampJPOS = new SimpleDateFormat("yyyyMMddHHmmssSSS");

private Date findTxnDate() throws ParseException
{
    Date date;
    String timeStamp = "20181115040613555";
    date = simpleDateFormatTimestampJPOS.parse(timeStamp);

    return date;
}

我不知道会发生什么,这是SimpleDateFormat,服务器等的问题。有人可以帮助我吗?

  

1018,我期望的是2018

服务器上的fyi Java版本

  

java版本“ 1.8.0_111”

     

Java(TM)SE运行时环境(内部版本1.8.0_111-b14)

     

Java HotSpot(TM)64位服务器VM(内部版本25.111-b14,混合模式)

3 个答案:

答案 0 :(得分:2)

SimpleDateFormat是线程不安全的,如果在多个线程中使用同一实例,则可能导致此类错误。

每次使用新实例,或使用一些线程安全的替代方法(例如FastDateFormat)

答案 1 :(得分:1)

我不知道这是否是您失败的原因,但如果是用于存储在数据库中,则用于存储时间的数据类型为TimeStamp,而不是Date

您提供的代码片段是以前在Java早期版本中使用的方式,正如其他人已经提到的那样,SimpleDateFormat不是线程安全的。

我也可以向您介绍另一种实现相同目标的方法,它使用来自线程安全的java.time包中的新的且对程序员更友好的类:

LocalDateTime newDate = null;
String dateTime = "20181115040613555";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS", Locale.ENGLISH);
try {
    newDate = LocalDateTime.parse(dateTime, dtf);
} catch (DateTimeParseException e) {
    throw new InvalidInputException("Invalid date input.");
}

更多信息可以在这里找到:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

答案 2 :(得分:0)

如果在多线程方案中使用代码,则可能会得到错误的结果,因为SimpleDateFormat不是线程安全的类。如果您使用Java8 +,请改用DateTimeFormatter。这是一个测试代码,用于验证SimpleDateFormat不是线程安全的类,希望对您有所帮助。

public class MultiThreadSimpleDateFormatClient {    
    public static void main(String[] args) {
        HandleDate handleDate = new HandleDate();
        Random random = new Random();
        Set<String> randomStrs = new HashSet<>();
        Thread thread1 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread2 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread3 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread4 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread5 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread6 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread7 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread8 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread9 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });
        Thread thread10 = new Thread(() -> {
            while (true) {
                int partOfYear = random.nextInt(10);
                handleDate.verifyNotThreadSafe("201" + partOfYear + "1115040613555");
            }
        });

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
        thread6.start();
        thread7.start();
        thread8.start();
        thread9.start();
        thread10.start();
    }
}

public class HandleDate {
    // this is not thread safe
    private SimpleDateFormat simpleDateFormatTimestampJPOS = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    public void verifyNotThreadSafe(String timeStamp) {
        try {
            // this is thread safe
            //SimpleDateFormat simpleDateFormatTimestampJPOS = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            Date date = simpleDateFormatTimestampJPOS.parse(timeStamp);
            LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
            String expectedYear = timeStamp.substring(0, 4);
            String actualYear = String.valueOf(localDateTime.getYear());
            if (!expectedYear.equals(actualYear)) {
                System.out.println("expected:" + expectedYear + ", but real:" + actualYear);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}