美文网首页
Java日期处理

Java日期处理

作者: Tinyspot | 来源:发表于2022-08-15 07:40 被阅读0次

    1. 日期时间

    1.1 TimeZone 时区

    • 格林威治标准时间 GMT+08:00
    • UTC+08:00
    • 夏令时 DST
    • Asia/Shanghai

    1.2 如何存储时间

    • Epoch Time : 从 1970年1月1日零点(格林威治时区/GMT+00:00)到现在经历的秒数,例:北京 2016-11-20 8:15:01 = 1479600901
    • Java 中用 long 类型的整型表示毫秒数, 北京 2016-11-20 8:15:01.123 = 1479600901123

    2. 日期 API

    • java.util.Data
    • java.util.Calendar

    2.1 Date

    • java.util.Date 类中的大部分方法已被 Calendar 类方法取代
    • new Date()
    • long getTime()
    • toGMTString()
    • toLocaleString()
    // Params: date – the milliseconds since January 1, 1970, 00:00:00 GMT.
    public Date(long date) {
      fastTime = date;
    }
    
    private static final long ONE_DAY_MILLISECONDS = 1000 * 60 * 60 * 24;
    
    public static void main(String[] args) {
        Date today = new Date();
        // today.toString() // Fri Aug 05 09:44:07 CST 2022
        System.out.println(today.toLocaleString());
    
        // Date(long date /* the milliseconds */)
        // 昨天 = 今天 减去 一天的毫秒值
        Date yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
        System.out.println(yesterday.toLocaleString());
    }
    

    2.2 Calendar

    public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
    
      // JANUARY which is 0
      public final static int MONTH = 2;
    
      // HOUR is used for the 12-hour clock (0 - 11)
      // HOUR_OF_DAY is used for the 24-hour
      public final static int HOUR_OF_DAY = 11;
    
      public static Calendar getInstance() {
          return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
      }
    
      /**
       * field – the given calendar field.
       * value – the value to be set for the given calendar field.
       */
      public void set(int field, int value) {}
    
      public final void set(int year, int month, int date, int hourOfDay, int minute, int second) {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
        set(HOUR_OF_DAY, hourOfDay);
        set(MINUTE, minute);
        set(SECOND, second);
      }
    }
    

    get(...) 获取时间

    Calendar calendar = Calendar.getInstance();
    Date time = calendar.getTime();
    System.out.println(calendar.getTime().toLocaleString());
    System.out.println(calendar.getTimeInMillis());
    
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minute = calendar.get(Calendar.MINUTE);
    int second = calendar.get(Calendar.SECOND);
    // 月份从 0 开始,要 +1
    System.out.println(year + "-" + (month + 1) + "-" + day + " " + hour + ":" + minute + ":" + second);
    

    set(...) 修改时间

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.DAY_OF_MONTH, 5);
    System.out.println(calendar.getTime().toLocaleString());
    

    add(..) 修改时间

    Calendar calendar = Calendar.getInstance();
    // 后一小时
    calendar.add(Calendar.HOUR_OF_DAY, 1);
    // 前一小时
    calendar.add(Calendar.HOUR_OF_DAY, -1);
    

    最大最小值

    Calendar calendar = Calendar.getInstance();
    int minimum = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
    int maximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    

    3. SimpleDateFormat

    查看 SimpleDateFormat 源码注释文档

    Letter Date or Time Component Examples
    y Year
    Y Week year 当天所在的周属于的年份,一周从周日开始,只要本周跨年,那么这周就算入下一年
    M Month in year
    D Day in year
    d Day in month
    H Hour in day (0-23)
    h Hour in am/pm (1-12)
    m Minute in hour
    s Second in minute
    S Millisecond
    e.g. yyyy-MM-dd HH:mm:ss 格式参考 java.text.SimpleDateFormat 的注释说明

    3.1 使用示例

    public class SimpleDateFormat extends DateFormat{
      public SimpleDateFormat(String pattern) {
         this(pattern, Locale.getDefault(Locale.Category.FORMAT));
      }
      public SimpleDateFormat(String pattern, Locale locale) {
      }
    }
    

    格式化:日期 -> 文本
    解析:文本 -> 日期

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String time = sdf.format(new Date());
    System.out.println(Timestamp.valueOf(time + " 00:00:00"));
    System.out.println(Timestamp.valueOf(time + " 23:59:59"));
    
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
    // 2022/01/01 要与 yyyy/MM/dd 格式保持一致
    Date date = simpleDateFormat.parse("2022/01/01");
    System.out.println(date.toString());
    

    时间戳就是一个 int 类型的数值,并不是什么timestamp字段,
    字段是 timestamp 存的就是时间格式的值,你要存成 1504064065 就用 int

    Timestamp ts = new Timestamp(System.currentTimeMillis());
    // ts = Timestamp.valueOf(time);
    System.out.println(ts);
    System.out.println(Timestamp.valueOf(time));
    System.out.println( new Timestamp(System.currentTimeMillis()));
    

    3.2 线程不安全

    public void demo() throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        ExecutorService executorService = Executors.newFixedThreadPool(10);
    
        Callable caller = new Caller(simpleDateFormat);
        List<Future<Date>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Future<Date> future = executorService.submit(caller);
            list.add(future);
        }
        for (Future<Date> future : list) {
            System.out.println(future.get());
        }
    
        executorService.shutdown();
    }
    
    class Caller implements Callable<Date> {
        private SimpleDateFormat simpleDateFormat;
        public Caller(SimpleDateFormat simpleDateFormat) {
            this.simpleDateFormat = simpleDateFormat;
        }
        @Override
        public Date call() throws Exception {
            // 线程不安全
            return simpleDateFormat.parse("2022-01-01");
        }
    }
    

    改进:

    @Override
    public Date call() throws Exception {
        // 加锁
        synchronized (simpleDateFormat) {
            return simpleDateFormat.parse("2022-01-01");
        }
    }
    

    3.3 使用线程安全的DateTimeFormatter

    public void demo() throws Exception {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        ExecutorService executorService = Executors.newFixedThreadPool(10);
    
        Callable caller = new Caller(dateTimeFormatter);
        List<Future<LocalDate>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Future<LocalDate> future = executorService.submit(caller);
            list.add(future);
        }
        for (Future<LocalDate> future : list) {
            System.out.println(future.get());
        }
    
        executorService.shutdown();
    }
    
    class Caller implements Callable<LocalDate> {
        private DateTimeFormatter dateTimeFormatter;
        public Caller(DateTimeFormatter dateTimeFormatter) {
            this.dateTimeFormatter = dateTimeFormatter;
        }
        @Override
        public LocalDate call() throws Exception {
            return LocalDate.parse("2022-01-01", dateTimeFormatter);
        }
    }
    

    3.4 线程不安全的原因

    public class SimpleDateFormat extends DateFormat{
      public SimpleDateFormat(String pattern) {
         this(pattern, Locale.getDefault(Locale.Category.FORMAT));
      }
      // java.text.DateFormat#format(java.util.Date)
      public final String format(Date date) {}
      // java.text.DateFormat#parse(java.lang.String)
      public Date parse(String source) throws ParseException {}
    }
    
    public final class LocalDate
            implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {}
    

    Reference

    相关文章

      网友评论

          本文标题:Java日期处理

          本文链接:https://www.haomeiwen.com/subject/xjwmvrtx.html