91

我尝试将字符串转换为时间戳时遇到问题。我有一个数组,其日期格式为yyyy-MM-dd,我想更改为yyyy-MM-dd HH:mm:ss.SSS. 所以,我使用这段代码:

final String OLD_FORMAT = "yyyy-MM-dd";
final String NEW_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
String oldDateString = createdArray[k];
String newDateString;

DateFormat formatter = new SimpleDateFormat(OLD_FORMAT);
Date d = formatter.parse(oldDateString);
((SimpleDateFormat) formatter).applyPattern(NEW_FORMAT);
newDateString = formatter.format(d);
System.out.println(newDateString);

Timestamp ts = Timestamp.valueOf(newDateString);
System.out.println(ts);

我得到以下结果。

2009-10-20 00:00:00.000

2009-10-20 00:00:00.0

但是当我尝试简单地做

String text = "2011-10-02 18:48:05.123";
ts = Timestamp.valueOf(text);
System.out.println(ts);

我得到了正确的结果:

2011-10-02 18:48:05.123

你知道我可能做错了什么吗?谢谢您的帮助。

4

11 回答 11

128

按照以下步骤获得正确的结果:

try {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
    Date parsedDate = dateFormat.parse(yourString);
    Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
} catch(Exception e) { //this generic but you can control another types of exception
    // look the origin of excption 
}

请注意,.parse(String)可能会抛出ParseException.

于 2013-09-20T11:07:20.543 回答
24
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Util {
  public static Timestamp convertStringToTimestamp(String strDate) {
    try {
      DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
       // you can change format of date
      Date date = formatter.parse(strDate);
      Timestamp timeStampDate = new Timestamp(date.getTime());

      return timeStampDate;
    } catch (ParseException e) {
      System.out.println("Exception :" + e);
      return null;
    }
  }
}
于 2015-05-20T06:17:21.983 回答
16

我想贡献现代答案。当这个问题在 2013 年被问到时,使用Timestamp该类是正确的,例如将日期时间存储到您的数据库中。今天的课程已经过时了。现代 Java 日期和时间 API 于三年半前的 2014 年春天随 Java 8 一起推出。我建议你改用这个。

根据您的情况和确切要求,有两种自然替代品Timestamp

  • Instant是时间线上的一个点。对于大多数目的,我认为使用它是最安全的。AnInstant独立于时区,即使在客户端设备和数据库服务器运行不同时区的情况下,它通常也能正常工作。
  • LocalDateTime是没有时区的日期和时间,例如 2011-10-02 18:48:05.123 (引用问题)。

现代 JDBC 驱动程序(JDBC 4.2 或更高版本)和其他用于数据库访问的现代工具将很乐意将 anInstant或 a存储LocalDateTime到 datatype 的数据库列中timestamp。我在此答案中使用的两个类和其他日期时间类都属于称为java.timeJSR-310 的现代 API。

将你的字符串转换为 是最简单的LocalDateTime,所以让我们先来看看:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
    String text = "2011-10-02 18:48:05.123";
    LocalDateTime dateTime = LocalDateTime.parse(text, formatter);
    System.out.println(dateTime);

这打印

2011-10-02T18:48:05.123

如果您的字符串是 yyyy-MM-dd 格式,请改为:

    String text = "2009-10-20";
    LocalDateTime dateTime = LocalDate.parse(text).atStartOfDay();
    System.out.println(dateTime);

这打印

2009-10-20T00:00

或者更好的是,获取输出LocalDate.parse()并将其存储到 datatype 的数据库列中date

在这两种情况下,从 a 转换LocalDateTime为 an 的过程Instant是:

    Instant ts = dateTime.atZone(ZoneId.systemDefault()).toInstant();
    System.out.println(ts);

我已经使用 JVM 的默认时区指定了转换,因为这是过时的类会使用的。但是,这很脆弱,因为您的程序的其他部分或在同一 JVM 中运行的其他程序可能会在我们的脚下更改时区设置。如果可以,请改为以区域/城市格式指定时区,例如:

    Instant ts = dateTime.atZone(ZoneId.of("Europe/Athens")).toInstant();
于 2017-11-15T17:16:29.357 回答
7

将 String 转换为 java.sql.Timestamp 的简单方法:

Timestamp t = new Timestamp(DateUtil.provideDateFormat().parse("2019-01-14T12:00:00.000Z").getTime());

DateUtil.java:

import java.text.SimpleDateFormat;
import java.util.TimeZone;

public interface DateUtil {

  String ISO_DATE_FORMAT_ZERO_OFFSET = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  String UTC_TIMEZONE_NAME = "UTC";

  static SimpleDateFormat provideDateFormat() {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ISO_DATE_FORMAT_ZERO_OFFSET);
    simpleDateFormat.setTimeZone(TimeZone.getTimeZone(UTC_TIMEZONE_NAME));
    return simpleDateFormat;
  }
}
于 2019-01-29T10:24:18.353 回答
3
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

Date date = formatter.parse(dateString);

Timestamp timestamp = new Timestamp(date.getTime());

System.out.println(timestamp);
于 2017-07-05T07:12:23.940 回答
3

只是为了完整起见,这里有一个带有 lambda 和方法参考的解决方案:

ISO格式?

描述:以下方法

  • String如果给出有效输入,则将带有模式的 a转换yyyy-MM-dd为 a Timestamp
  • 返回 a null,如果null给定了一个值,
  • DateTimeParseException如果给出了无效的输入,则抛出一个

代码

static Timestamp convertStringToTimestamp(String strDate) {
    return Optional.ofNullable(strDate) // wrap the String into an Optional
                   .map(str -> LocalDate.parse(str).atStartOfDay()) // convert into a LocalDate and fix the hour:minute:sec to 00:00:00
                   .map(Timestamp::valueOf) // convert to Timestamp
                   .orElse(null); // if no value is present, return null
}


验证:可以使用这些单元测试来测试此方法:(使用Junit5Hamcrest

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenValidInput() {
    // given
    String strDate = "2020-01-30";

    // when
    final Timestamp result = convertStringToTimestamp(strDate);

    // then
    final LocalDateTime dateTime = LocalDateTime.ofInstant(result.toInstant(), ZoneId.systemDefault());
    assertThat(dateTime.getYear(), is(2020));
    assertThat(dateTime.getMonthValue(), is(1));
    assertThat(dateTime.getDayOfMonth(), is(30));
}

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenInvalidInput() {
    // given
    String strDate = "7770-91-30";

    // when, then
    assertThrows(DateTimeParseException.class, () -> convertStringToTimestamp(strDate));
}

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenNullInput() {
    // when
    final Timestamp result = convertStringToTimestamp(null);

    // then
    assertThat(result, is(nullValue()));
}


另一种格式?

通常,要解析的字符串带有另一种格式。处理它的一种方法是使用格式化程序将其转换为另一种格式。这是一个例子:

输入:20200130 11:30

图案:yyyyMMdd HH:mm

输出:此输入的时间戳

代码

static Timestamp convertStringToTimestamp(String strDate) {
    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm");
    return Optional.ofNullable(strDate) //
                   .map(str -> LocalDateTime.parse(str, formatter))
                   .map(Timestamp::valueOf) //
                   .orElse(null);
}

测试

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenValidInput() {
    // given
    String strDate = "20200130 11:30";

    // when
    final Timestamp result = convertStringToTimestamp(strDate);

    // then
    final LocalDateTime dateTime = LocalDateTime.ofInstant(result.toInstant(), ZoneId.systemDefault());
    assertThat(dateTime.getYear(), is(2020));
    assertThat(dateTime.getMonthValue(), is(1));
    assertThat(dateTime.getDayOfMonth(), is(30));
    assertThat(dateTime.getHour(), is(11));
    assertThat(dateTime.getMinute(), is(30));
}
于 2020-01-16T13:29:59.173 回答
2
DateFormat formatter;
formatter = new SimpleDateFormat("dd/MM/yyyy");
Date date = (Date) formatter.parse(str_date);
java.sql.Timestamp timeStampDate = new Timestamp(date.getTime());
于 2016-03-03T12:57:11.107 回答
1

这就是我所做的:

Timestamp timestamp = Timestamp.valueOf(stringValue);

其中stringValue可以是任何格式的日期/时间。

于 2021-02-15T12:28:11.840 回答
0

我确定解决方案是您的 oldDateString 类似于“2009-10-20”。显然,这不包含任何低于天数的时间数据。如果你用你的新格式化程序格式化这个字符串,它应该从哪里得到分钟、秒和毫秒?

所以结果是绝对正确的:2009-10-20 00:00:00.000

你需要解决这个问题,是你第一次格式化之前的原始时间戳(包括时间数据)。

于 2014-06-26T08:16:06.163 回答
0

首先将您的日期字符串date转换为然后timestamp使用以下行将其转换为

Date date=new Date();
Timestamp timestamp = new Timestamp(date.getTime());//instead of date put your converted date
Timestamp myTimeStamp= timestamp;
于 2013-09-20T11:01:46.890 回答
0

可以试一次吗...

String dob="your date String";
String dobis=null;
final DateFormat df = new SimpleDateFormat("yyyy-MMM-dd");
final Calendar c = Calendar.getInstance();
try {
    if(dob!=null && !dob.isEmpty() && dob != "")
    {
    c.setTime(df.parse(dob));
    int month=c.get(Calendar.MONTH);
    month=month+1;
    dobis=c.get(Calendar.YEAR)+"-"+month+"-"+c.get(Calendar.DAY_OF_MONTH);
    }

}
于 2013-09-20T11:09:37.970 回答