在Java中将时间戳字符串转换为long

时间:2015-07-30 04:43:19

标签: java string numberformatexception

我必须从DB中获取时间戳并仅检索时间并比较两次。

//下面是字符串值

 String st1 = "2015-07-24T09:39:14.000Z";      
 String st2 = "2015-07-24T09:45:44.000Z";

//仅检索时间 09:39:14

 String s = st1.substring(st1.indexOf("T") + 1, st1.indexOf(".0"));

//字符串为Long。

 Long time = Long.parseLong(s);

 Long tim1=Long.valueOf(s).longValue();

错误:

java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Long.parseLong(Unknown Source)
    at java.lang.Long.parseLong(Unknown Source)

6 个答案:

答案 0 :(得分:8)

尝试这种方式,示例代码:

java.sql.Timestamp ts2 = java.sql.Timestamp.valueOf("2015-07-24T09:45:44.000Z");
long tsTime2 = ts2.getTime();

答案 1 :(得分:3)

最简单的解决方案是使用Java 8的日期/时间API

LocalDateTime from = LocalDateTime.parse("2015-07-24T09:39:14.000Z", DateTimeFormatter.ISO_DATE_TIME);
LocalDateTime to = LocalDateTime.parse("2015-07-24T09:45:44.000Z", DateTimeFormatter.ISO_DATE_TIME);
System.out.println(from + " - " + to);

LocalTime fromTime = from.toLocalTime();
LocalTime toTime = to.toLocalTime();

System.out.println(fromTime + " - " + toTime);

System.out.println(fromTime + " before " + toTime + " = " + fromTime.isBefore(toTime));
System.out.println(fromTime + " after " + toTime + " = " + fromTime.isAfter(toTime));
System.out.println(fromTime + " equals " + toTime + " = " + fromTime.equals(toTime));
System.out.println(fromTime + " compareTo " + toTime + " = " + fromTime.compareTo(toTime));

哪个输出

2015-07-24T09:39:14 - 2015-07-24T09:45:44
09:39:14 - 09:45:44
09:39:14 before 09:45:44 = true
09:39:14 after 09:45:44 = false
09:39:14 equals 09:45:44 = false
09:39:14 compareTo 09:45:44 = -1

如果您不使用Java 8,请使用类似方式的Joda-Time

Joda-Time示例......

import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
import org.joda.time.format.ISODateTimeFormat;

public class JodaTimeTest {

    public static void main(String[] args) {
        LocalDateTime from = LocalDateTime.parse("2015-07-24T09:39:14.000Z", ISODateTimeFormat.dateTime());
        LocalDateTime to = LocalDateTime.parse("2015-07-24T09:45:44.000Z", ISODateTimeFormat.dateTime());

        LocalTime fromTime = from.toLocalTime();
        LocalTime toTime = to.toLocalTime();

        System.out.println(fromTime + " - " + toTime);

        System.out.println(fromTime + " before " + toTime + " = " + fromTime.isBefore(toTime));
        System.out.println(fromTime + " after " + toTime + " = " + fromTime.isAfter(toTime));
        System.out.println(fromTime + " equals " + toTime + " = " + fromTime.equals(toTime));
        System.out.println(fromTime + " compareTo " + toTime + " = " + fromTime.compareTo(toTime));
    }

}

哪个输出

09:39:14.000 - 09:45:44.000
09:39:14.000 before 09:45:44.000 = true
09:39:14.000 after 09:45:44.000 = false
09:39:14.000 equals 09:45:44.000 = false
09:39:14.000 compareTo 09:45:44.000 = -1

答案 2 :(得分:2)

另一个选择是使用SimpleDateFormat(可能不是最佳比较JODA时间)

public static void main(String[] args) throws ParseException {
        String st1 = "2015-07-24T09:39:14.000Z";
        String st2 = "2015-07-24T09:45:44.000Z";

        String time1 = st1.substring(st1.indexOf("T") + 1, st1.indexOf(".0"));
        String time2 = st2.substring(st2.indexOf("T") + 1, st2.indexOf(".0"));

        Date dateTime1 = new java.text.SimpleDateFormat("HH:mm").parse(time1);
        Date dateTime2 = new java.text.SimpleDateFormat("HH:mm").parse(time2);

        System.out.println(dateTime1.after(dateTime2));

    }

答案 3 :(得分:2)

TL;博士

myResultSet.getObject(                         // Use JDBC 4.2 or later to get *java.time* objects rather than mere strings.
    … ,                                        // Specify the column in database of type `TIMESTAMP WITH TIME ZONE`.
    Instant.class                              // Extract from database as a `Instant` object in UTC, via JDBC.
)
.atZone( ZoneId.of( "Africa/Tunis" ) )         // Adjust into a time zone other than UTC. Returns a `ZonedDateTime` object.
.toLocalDate()                                 // Extract the date-only value, without time-of-day and without time zone. Returns a `LocalDate` object.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) )   // Determine the first moment of the day (not always 00:00). Returns a `ZonedDateTime` object.

和...

Duration.between( zdtStartOfDay , zdt )        // Represent the span of time between the first moment of the day and the target moment. Each argument is a `ZonedDateTime` object here.
    .toMillis()                                // Get entire span as a count of milliseconds. Returns a `long` primitive.
  • 不需要字符串。
  • 无需java.sql.Timestamp

java.time

现代方法使用 java.time 类来取代麻烦的旧遗留类,例如java.sql.Timestamp& Date& Calendar

使用 java.time Answer by MadProgrammer朝着正确的方向发展,但使用了错误的类:LocalDateTime类故意缺少任何时区或偏移的概念-UTC但我们的输入字符串确实如此。输入字符串末尾的ZZulu的缩写,表示UTC。抛弃有价值的信息(区域/偏移信息)不是一个好习惯。

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.parse( "2015-07-24T09:39:14.000Z" ) ;

智能对象,而不是哑字符串

  

我必须从DB中获取时间戳并仅检索时间并比较两次。

     

下面是字符串值

使用适当的对象与数据库交换数据,而不仅仅是字符串。

从JDBC 4.2开始,您可以通过getObject&直接交换 java.time 对象。 setObject

Instant instant = myResultSet( … , Instant.class ) ;

您只是直接从类似于SQL标准TIMESTAMP WITH TIME ZONE的类型的数据库列中获取日期时间。

要将数据发送到数据库,请使用带占位符的PreparedStatement

myPreparedStatement.setObject( … , instant ) ;

根据定义,通过JDBC从数据库检索的Instant对象是UTC。要获取时间,您必须指定用户期望的区域的挂钟时间(时区)。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4个字母伪区域,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;

应用该时区以获取ZonedDateTime个对象。 InstantZonedDateTime代表同一时刻,即时间轴上的相同点。这是一个需要理解的关键概念。两个朋友在电话上聊天,一个在加拿大魁北克,一个在法国巴黎,每个人同时在墙上同时看到一个时钟,但看到他们特定地区的人们使用不同的时间。

ZoneDateTime zdt = instant.atZone( z ) ;

如果您只关心时间,请提取LocalTime对象。

LocalTime lt = zdt.toLocalTime(); 

以标准ISO 8601格式生成String

String output = lt.toString();

以本地化格式生成字符串。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
String output = lt.format( f ) ;

但是你似乎想要从一天开始就计算一些东西 - 你的问题不明确。也许你想要一整秒或几毫秒的计数,或者我不知道是什么。

我们必须在期望/预期的时区内获得当天的开始。不要假设当天00:00:00开始。由于夏令时(DST)等异常,该日可能会在另一个时间开始,例如01:00:00。让java.time确定当天的开始。

ZonedDateTime zdtStartOfDay = zdt.toLocalDate().atStartOfDay( z ) ;

将经过的时间跨度计算为Duration

Duration d = Duration.between( zdtStartOfDay , zdt ) ;

将整个范围提取为整数秒。

long secondsSinceStartOfDay = d.toSeconds() ;

将整个范围提取为毫秒数。

long millisSinceStartOfDay = d.toMillis() ;

小心数据丢失。 java.time 类的分辨率为纳秒,因此当您调用to…方法时,如果存在,则忽略值的更精细部分。

关于 java.time

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

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 4 :(得分:1)

        String date = "2015-07-24T09:39:14.000Z";
        //Now we are getting the time only from the above string.
        String time = date.substring(12, 19); 
        System.out.println("Time is: "+time);
        //Since we cannot convert symbols like":" to long we are removing them.
        String timeInLong = time.replaceAll(":", "");
        System.out.println("Time in long format : "+Long.parseLong(timeInLong));

答案 5 :(得分:0)

您可以尝试使用下一个代码,我使用库joda-time

java.sql.Timestamp ts2 = java.sql.Timestamp.valueOf("2015-07-24T09:45:44.000Z"); long dateLong=new DateTime(ts2).toDate().getTime();