Java 如何通过给定一年来获取字符串类型或时间戳类型

Java 如何通过给定一年来获取字符串类型或时间戳类型,java,Java,有一个要求是通过给出一个整数年来获得全年的开始时间和结束时间,例如,给定一个变量int year=2017,我想得到开始时间字符串“2017-01-01 00:00:00”和结束时间字符串“2017-12-31 23:59:59”,或者获取starttime时间戳1483200000和endtime时间戳1514735999。2结果对我们来说是可以的,我应该如何使用java8或更低版本?我知道: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-

有一个要求是通过给出一个整数年来获得全年的开始时间和结束时间,例如,给定一个变量
int year=2017
,我想得到开始时间
字符串“2017-01-01 00:00:00”
和结束时间
字符串“2017-12-31 23:59:59”
,或者获取starttime时间戳1483200000和endtime时间戳1514735999。2结果对我们来说是可以的,我应该如何使用java8或更低版本?我知道:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String datetime = sdf.format(new Date(*timestamp*))
但我不知道如何在给定年份获得时间戳,请帮助检查

int year = 2017;

// Using LocalDateTime (Java 8+ or Java 6+ with ThreeTen backport)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String start1 = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0).format(dtf);
String stop1 = LocalDateTime.of(year, Month.DECEMBER, 31, 23, 59, 59).format(dtf);
System.out.println(start1 + " - " + stop1);

// Using Calendar (antiquated)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, Calendar.JANUARY, 1);
String start2 = sdf.format(cal.getTime());
cal.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
String stop2 = sdf.format(cal.getTime());
System.out.println(start2 + " - " + stop2);
输出

2017-01-01 00:00:00-2017-12-31 23:59:59
2017-01-01 00:00:00 - 2017-12-31 23:59:59

您可以使用
java.sql.Timestamp

import java.util.Date;
import java.sql.Timestamp;

public class Main
{
    public static void main( String[] args )
    {

       Date date= new Date();

       long time = date.getTime();
       System.out.println("Time (Milliseconds): " + time);

       Timestamp ts = new Timestamp(time);
       System.out.println("Current Time Stamp: " + ts);
    }
}
仅使用Java 8:

int year = 2017;

// using one of the predefined format from enum java.time.format.FormatStyle
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);

LocalDateTime beginDate = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0, 0);
LocalDateTime endDate = LocalDateTime.of(year, Month.DECEMBER, 31, 23, 59, 59);

String beginDateFormatted = beginDate.format(formatter);
String endDateFormatted = endDate.format(formatter);

long beginTimestamp = this.beginDate.toInstant(ZoneOffset.UTC).toEpochMilli();
long endTimestamp = this.endDate.toInstant(ZoneOffset.UTC).toEpochMilli();
检查工作示例。

使用半开间隔 正如巴兹尔·布尔克在评论中所说:使用半开放的间隔。也就是说,将2017年定义为从2017年第一个时刻(含)到2018年第一个时刻(不含)的时间。因此,在开始时间上或之后,严格来说在结束时间之前的任何时刻都属于一年

哲学论据:它让我们不用去决定是跑到一年中的最后一秒、最后一毫秒还是最后一纳秒。a即使我们最后一辆nano车,我们仍然会在今年排除一辆完整的nano车,这是不正确的。是的,我知道,你的应用程序只需要几秒钟的粒度,所以“没关系”。但是如果下一个版本确实需要更精细的粒度呢?即使它不会,你也不应该想在你的程序中填入错误或不准确的内容,即使用户没有看到它们的任何症状

实际论证:半开区间简化了一些事情,包括计算时间戳和应用时间戳

    ZoneId zone = ZoneId.of("Asia/Singapore");

    Year year = Year.of(2017);

    long startTime = year.atDay(1).atStartOfDay(zone).toEpochSecond();
    System.out.println(startTime);

    long endTime = year.plusYears(1).atDay(1).atStartOfDay(zone).toEpochSecond();
    System.out.println(endTime);
此代码段的输出为:

如果你绝对坚持,你当然可以从后面的数字中减去1


请注意,使用
atStartOfDay()
还可以避免我们假设一天从00:00:00开始,在23:59:59后一秒结束。有趣的时间异常可能导致情况并非如此。这种异常情况存在于时区数据库中,Java在查询时区中一天的开始时会考虑到这些异常情况。

到目前为止,您尝试了什么?你看过java.time包了吗?在Java 8下面,使用我已经编好的问题,可以帮助检查它。您还可以修改Java的
日历
实例。该代码省略了一年中的最后60秒,因此这种方法无法计算全年。更好的方法是在日期时间处理中常用的半开放方法,其中开始是包含的,而结束是独占的。这些糟糕的日期时间类在几年前被JSR 310中定义的现代java.time类所取代。此代码假设一年从00:00:00.0开始。在所有的地方,在所有的年份,这可能并不总是正确的。这段代码还假设每年都在23:59:59结束,这可能并不总是正确的。
1483200000
1514736000