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 {}
网友评论