简体   繁体   English

Java:将字符串转换为时间戳

[英]Java: Convert String to TimeStamp

I have an issue while I try to convert a String to a TimeStamp.我在尝试将字符串转换为时间戳时遇到问题。 I have an array that has the date in the format of yyyy-MM-dd and I want to change in the format of yyyy-MM-dd HH:mm:ss.SSS .我有一个数组,其日期格式为yyyy-MM-dd ,我想更改为yyyy-MM-dd HH:mm:ss.SSS So, I use this code:所以,我使用这个代码:

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

and I get the following result.我得到以下结果。

2009-10-20 00:00:00.000 2009-10-20 00:00:00.000

2009-10-20 00:00:00.0 2009-10-20 00:00:00.0

but when I try to simply do但是当我试着简单地做

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

I get the right result:我得到正确的结果:

2011-10-02 18:48:05.123 2011-10-02 18:48:05.123

Do u know what I might be doing wrong?你知道我可能做错了什么吗? Thanks for the help.谢谢您的帮助。

Follow these steps for a correct result:请按照以下步骤获得正确的结果:

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 
}

Please note that .parse(String) might throw a ParseException .请注意.parse(String)可能会抛出ParseException

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

I should like to contribute the modern answer.我想贡献现代答案。 When this question was asked in 2013, using the Timestamp class was right, for example for storing a date-time into your database.当在 2013 年提出这个问题时,使用Timestamp类是正确的,例如将日期时间存储到您的数据库中。 Today the class is long outdated.今天的课程已经过时了。 The modern Java date and time API came out with Java 8 in the spring of 2014, three and a half years ago.现代 Java 日期和时间 API 于 2014 年春季(三年半前)随 Java 8 发布。 I recommend you use this instead.我建议你改用这个。

Depending on your situation an exact requirements, there are two natural replacements for Timestamp :根据您的情况和确切要求, Timestamp有两种自然替代品:

  • Instant is a point on the time-line. Instant是时间线上的一个点。 For most purposes I would consider it safest to use this.对于大多数目的,我认为使用它是最安全的。 An Instant is independent of time zone and will usually work well even in situations where your client device and your database server run different time zones. Instant与时区无关,即使在您的客户端设备和数据库服务器运行不同时区的情况下,它通常也能很好地工作。
  • LocalDateTime is a date and time of day without time zone, like 2011-10-02 18:48:05.123 (to quote the question). LocalDateTime是没有时区的日期和时间,例如 2011-10-02 18:48:05.123(引用问题)。

A modern JDBC driver (JDBC 4.2 or higher) and other modern tools for database access will be happy to store either an Instant or a LocalDateTime into your database column of datatype timestamp .现代 JDBC 驱动程序(JDBC 4.2 或更高版本)和其他用于数据库访问的现代工具很乐意将InstantLocalDateTime存储到数据类型为timestamp数据库列中。 Both classes and the other date-time classes I am using in this answer belong to the modern API known as java.time or JSR-310.我在此答案中使用的类和其他日期时间类都属于称为java.time或 JSR-310 的现代 API。

It's easiest to convert your string to LocalDateTime , so let's take that first:将字符串转换为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);

This prints这打印

2011-10-02T18:48:05.123

If your string was in yyyy-MM-dd format, instead do:如果您的字符串是 yyyy-MM-dd 格式,请改为:

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

This prints这打印

2009-10-20T00:00

Or still better, take the output from LocalDate.parse() and store it into a database column of datatype date .或者更好的是,从LocalDate.parse()获取输出并将其存储到数据类型为date的数据库列中。

In both cases the procedure for converting from a LocalDateTime to an Instant is:在这两种情况下,从LocalDateTime转换为Instant是:

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

I have specified a conversion using the JVM's default time zone because this is what the outdated class would have used.我已经使用 JVM 的默认时区指定了一个转换,因为这是过时的类将使用的。 This is fragile, though, since the time zone setting may be changed under our feet by other parts of your program or by other programs running in the same JVM.但是,这很脆弱,因为程序的其他部分或在同一 JVM 中运行的其他程序可能会更改时区设置。 If you can, specify a time zone in the region/city format instead, for example:如果可以,请改为以地区/城市格式指定时区,例如:

    Instant ts = dateTime.atZone(ZoneId.of("Europe/Athens")).toInstant();

The easy way to convert String to java.sql.Timestamp:将 String 转换为 java.sql.Timestamp 的简单方法:

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

DateUtil.java: 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;
  }
}
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

Date date = formatter.parse(dateString);

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

System.out.println(timestamp);

Just for the sake of completeness, here is a solution with lambda and method reference:为了完整起见,这里有一个带有 lambda 和方法参考的解决方案:

ISO format? ISO格式?

Description : The following method说明:以下方法

  • converts a String with the pattern yyyy-MM-dd into a Timestamp , if a valid input is given,如果给出有效输入,则将具有yyyy-MM-dd模式的String转换为Timestamp
  • returns a null , if a null value is given,返回一个null ,如果给定一个null值,
  • throws a DateTimeParseException , if an invalid input is given如果给出无效输入,则抛出DateTimeParseException

Code :代码

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
}


Validation : This method can be tested with those unit tests: (with Junit5 and Hamcrest )验证:可以使用这些单元测试来测试此方法:(使用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()));
}


Another format?另一种格式?

Usually, the string to parse comes with another format.通常,要解析的字符串带有另一种格式。 A way to deal with it is to use a formatter to convert it to another format.处理它的一种方法是使用格式化程序将其转换为另一种格式。 Here is an example:下面是一个例子:

Input: 20200130 11:30输入: 20200130 11:30

Pattern: yyyyMMdd HH:mm图案: yyyyMMdd HH:mm

Output: Timestamp of this input输出:此输入的时间戳

Code :代码

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 :测试

@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));
}
DateFormat formatter;
formatter = new SimpleDateFormat("dd/MM/yyyy");
Date date = (Date) formatter.parse(str_date);
java.sql.Timestamp timeStampDate = new Timestamp(date.getTime());

first convert your date string to date then convert it to timestamp by using following set of line首先将您的日期字符串转换为date然后使用以下一组行将其转换为timestamp

Date date=new Date();
Timestamp timestamp = new Timestamp(date.getTime());//instead of date put your converted date
Timestamp myTimeStamp= timestamp;

can you try it once...你能不能试一次...

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

}

I'm sure the solution is that your oldDateString is something like "2009-10-20".我确定解决方案是您的 oldDateString 类似于“2009-10-20”。 Obviously this does not contain any time data lower than days.显然,这不包含任何低于天的时间数据。 If you format this string with your new formatter where should it get the minutes, seconds and milliseconds from?如果你用你的新格式化程序格式化这个字符串,它应该从哪里获取分钟、秒和毫秒?

So the result is absolutely correct: 2009-10-20 00:00:00.000所以结果是绝对正确的:2009-10-20 00:00:00.000

What you'll need to solve this, is the original timestamp (incl. time data) before your first formatting.您需要解决这个问题,是您第一次格式化之前的原始时间戳(包括时间数据)。

This is what I did:这就是我所做的:

Timestamp timestamp = Timestamp.valueOf(stringValue);

where stringValue can be any format of Date/Time.其中stringValue可以是任何日期/时间格式。

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

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