2012-12-15 45 views
12

Tôi đang lưu trữ thời gian/ngày trong cơ sở dữ liệu bằng dấu thời gian unix. Tôi muốn sau đó nhận được tất cả các trường hợp vào một ngày nhất định vì vậy tôi cần tính toán dấu thời gian cho ngày bắt đầu trong ngày để truy vấn cơ sở dữ liệu.Nhận dấu thời gian cho ngày bắt đầu của ngày

Tôi đã thực hiện một điều tương tự trong php bằng cách chuyển mktime giá trị cho ngày/tháng/năm từ đối tượng ngày và đặt giờ và phút sang 0. Có vẻ như không có chức năng tương tự cho điều này trong java/android (các chức năng để nhận các phần cụ thể của ngày không được chấp nhận)

Có ai có thể đưa ra một số hướng dẫn về điều này không? Cảm ơn

Edit:

Ok vì vậy tôi nhận ra điều này có thể làm việc:

public static int startOfDay(Timestamp time) { 
     Calendar cal = dateToCalendar(new Date(time.getTime())); 
     cal.add(Calendar.HOUR_OF_DAY, -Calendar.HOUR_OF_DAY); 
     cal.add(Calendar.MINUTE, -Calendar.MINUTE); 
     cal.add(Calendar.SECOND, -Calendar.SECOND); 
     Log.i("Time", cal.getTime().toString());   
     return (int) cal.getTimeInMillis()/1000; 
} 

Tuy nhiên khi tôi chạy này chỉ là bây giờ tôi nhận:

Sat 15 tháng 12 01:24:00 GMT 2012

Số giây là đúng nhưng giờ và phút sai?

Trả lời

32

Khi xử lý thời gian, bạn nên luôn xem xét múi giờ. Dấu thời gian cơ sở dữ liệu của bạn phải luôn được lưu trữ trong một múi giờ (ví dụ: UTC). Tính toán của bạn sau đó nên xem xét rằng người dùng có thể ở các múi giờ khác nhau và họ có thể thay đổi múi giờ.

Nếu bạn muốn tính thời gian bắt đầu trong ngày theo múi giờ mà người dùng hiện đã đặt trong điện thoại của mình. Tạo dụ Calendar với:

Calendar cal = Calendar.getInstance(); 

Để có được dụ cho việc sử dụng múi giờ cụ thể:

// use UTC time zone 
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 

Sau đó thiết lập các đầu ngày:

cal.setTime(time); // compute start of the day for the timestamp 
cal.set(Calendar.HOUR_OF_DAY, 0); 
cal.set(Calendar.MINUTE, 0); 
cal.set(Calendar.SECOND, 0); 
cal.set(Calendar.MILLISECOND, 0); 
6
public static int startOfDay(Timestamp time) { 
    Calendar cal = Calendar.getInstance(); 
    cal.setTimeInMillis(time.getTime()); 
    cal.set(Calendar.HOUR_OF_DAY, 0); //set hours to zero 
    cal.set(Calendar.MINUTE, 0); // set minutes to zero 
    cal.set(Calendar.SECOND, 0); //set seconds to zero 
    Log.i("Time", cal.getTime().toString());   
    return (int) cal.getTimeInMillis()/1000; 
} 
+0

Cảm ơn bạn đã không nhận ra nó hoạt động như thế này. –

+0

cách gọi phương thức này –

1

tl; dr

ZoneId z = ZoneId.of("America/Montreal"); 
long secondsSinceEpoch = ZonedDateTime.now(z).toLocalDate().asStartOfDay(z).toEpochSecond() ; 

Chi tiết

Đã chấp nhận Answer by Tomik là chính xác nhưng đã lỗi thời. Các lớp thời gian cũ di sản phiền hà đã được thay thế bởi các lớp java.time.

Vì câu trả lời đó được thông báo, bạn phải xem xét múi giờ khi bắt đầu một ngày. Múi giờ rất quan trọng trong việc xác định ngày tháng. Đối với bất kỳ thời điểm cụ thể nào, ngày thay đổi trên toàn cầu theo múi giờ. Ví dụ, một vài phút sau nửa đêm ở Paris Pháp là một ngày mới trong khi vẫn “ngày hôm qua” ở Montréal Québec.

ZoneId z = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = ZonedDateTime.now(z); 

Lấy khoảnh khắc đầu tiên trong ngày yêu cầu thông qua LocalDate. Lớp LocalDate đại diện cho giá trị chỉ ngày mà không có thời gian trong ngày và không có múi giờ.

LocalDate today = zdt.toLocalDate(); 
ZonedDateTime zdtTodayStart = today.atStartOfDay(z); 

Lưu ý rằng chúng tôi cho phép java.thời gian xác định ngày bắt đầu thay vì giả định và mã hóa cứng 00:00:00. Do Thời gian tiết kiệm ánh sáng ban ngày (DST) và các dị thường khác, ngày có thể bắt đầu vào một thời điểm khác chẳng hạn như 01:00:00.

Dường như, theo số unix timestamp, bạn có nghĩa là đếm tổng số giây kể từ giây phút đầu tiên của năm 1970 ở dạng UTC. Lớp ZonedDateTime có phương pháp cung cấp cho bạn số đó. Lưu ý điều này có nghĩa là mất dữ liệu vì ZonedDateTime có thể có một phần nhỏ của giây với độ phân giải nano giây.

long secondsSinceEpoch = zdtTodayStart.toEpochSecond(); 

Về java.time

Khung java.time được xây dựng vào Java 8 và sau đó. Các lớp này thay thế các lớp học ngày giờ phiền hà cũ như java.util.Date, .Calendar, & java.text.SimpleDateFormat.

Dự án Joda-Time, hiện đang ở maintenance mode, khuyên di chuyển sang java.time.

Để tìm hiểu thêm, hãy xem Oracle Tutorial. Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích.

Hầu hết các chức năng java.time được back-chuyển đến Java 6 & 7 trong ThreeTen-Backport và tiếp tục thích nghi với Android trong ThreeTenABP (xem How to use…).

Dự án ThreeTen-Extra mở rộng java.time với các lớp bổ sung. Dự án này là một nền tảng chứng minh cho những bổ sung có thể có trong tương lai vào java.time. Bạn có thể tìm thấy một số lớp học hữu ích tại đây như Interval, YearWeek, YearQuarter và hơn thế nữa.

3

Bạn nghĩ sao về giải pháp đơn giản này?

Long currentDayStart = timestamp - timestamp%86400000; 
Long currentDayEnd = timestamp+86399999; 

Thay đổi múi giờ cho dấu thời gian là không cần thiết. Thêm tại đây: https://stackoverflow.com/a/23062640

Các vấn đề liên quan