Làm cách nào để chuyển đổi DateTime thành số giây kể từ năm 1970?


119

Tôi đang cố chuyển đổi một biến DateTime trong C # thành thời gian Unix, tức là số giây kể từ ngày 1 tháng 1 năm 1970. Có vẻ như DateTime thực sự được triển khai dưới dạng số 'tích tắc' kể từ ngày 1 tháng 1 năm 1970.

Suy nghĩ hiện tại của tôi là trừ ngày 1 tháng 1 năm 1970 khỏi DateTime của tôi như thế này:

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
return span.TotalSeconds;

Có cách nào tốt hơn?


Câu trả lời:


195

Về cơ bản là vậy. Đây là những phương pháp tôi sử dụng để chuyển đổi sang và từ Unix epoch time:

public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    return origin.AddSeconds(timestamp);
}

public static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    TimeSpan diff = date.ToUniversalTime() - origin;
    return Math.Floor(diff.TotalSeconds);
}

Cập nhật: Kể từ .Net Core 2.1 và .Net Standard 2.1, một DateTime tương đương với Unix Epoch có thể được lấy từ tĩnh DateTime.UnixEpoch.


1
Cần lưu ý rằng nếu bạn muốn chuyển đổi sang millseconds để có dấu thời gian chính xác hơn hoặc khả năng tương thích đối tượng Javascript Date (), bạn cần sử dụng long thay vì int cho loại dấu thời gian.
Soviut

3
Không làm việc cho tôi. Câu trả lời này đã thực hiện thủ thuật: stackoverflow.com/questions/249760/…
Zeezer

@Jonny - ToUniversalTime () chuyển đổi thành UTC, vì vậy nó tính đến UTC.
Dave Swersky

4
DateTime origin = new DateTime (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); Điều thú vị là không ai đề nghị điều này. Thông thường, bạn sẽ có mili giây biểu thị thời gian Utc. Và nếu bạn không t specify this explicitly and somewhere later in code youcó ToUniversalTime () thì bạn sẽ có thời gian Utc kém, vì theo mặc định DateTime KHÔNG phải là Utc.
steavy

52

Nếu phần còn lại của hệ thống của bạn OK với DateTimeOffset thay vì DateTime, thì có một tính năng thực sự tiện lợi:

long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();

7
Đây là một cách gọn gàng hơn, nhưng nó chỉ có sẵn trong khuôn khổ 4,6 msdn.microsoft.com/en-us/library/…
Oscar Fraxedas

1
Đẹp. Và tất nhiên để chuyển từ unix sang DateTimeOffset, bạn có thể sử dụng var time = DateTimeOffset.FromUnixTimeSeconds(5000); MS Doc
Jordan

22

Điều duy nhất tôi thấy là nó được cho là kể từ Nửa đêm ngày 1 tháng 1 năm 1970 UTC

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;

7
Nó có nên là DateTime.UtcNow không?
oferei

14

Bạn có thể muốn sử dụng DateTime.UtcNow để tránh vấn đề về múi giờ

TimeSpan span= DateTime.UtcNow.Subtract(new DateTime(1970,1,1,0,0,0)); 

Cách duy nhất để tránh các vấn đề về múi giờ là 1) không biết gì về múi giờ và chỉ hỗ trợ một múi giờ, hoặc 2) xử lý múi giờ (ít nhất) ở mọi nơi bạn giao tiếp với hệ thống hoặc người dùng cuối khác. Đặc biệt, việc sử dụng UTC ở mọi nơi trong nội bộ chỉ là một phần của trận chiến. Trong trường hợp đầu tiên, việc thêm lịch ngày UTC thực sự làm cho vấn đề trở nên tồi tệ hơn, cho đến khi bạn sẵn sàng thực hiện tất cả (2), vì bạn chuyển từ hỗ trợ bất kỳ múi giờ nào sang chỉ hỗ trợ UTC.
jpaugh

1

Cách tiếp cận đó sẽ tốt nếu ngày-giờ được đề cập ở UTC hoặc đại diện cho giờ địa phương trong khu vực chưa bao giờ quan sát giờ tiết kiệm ánh sáng ban ngày. Các quy trình khác biệt về DateTime không tính đến Giờ tiết kiệm ánh sáng ban ngày và do đó sẽ coi nửa đêm ngày 1 tháng 6 là bội số của 24 giờ sau nửa đêm ngày 1 tháng 1. Tôi không biết bất kỳ điều gì trong Windows báo cáo các quy tắc tiết kiệm ánh sáng ban ngày lịch sử cho hiện tại ngôn ngữ, vì vậy tôi không nghĩ rằng có bất kỳ cách tốt nào để xử lý chính xác bất kỳ lúc nào trước khi thay đổi quy tắc tiết kiệm ánh sáng ban ngày gần đây nhất.


0

Bạn có thể tạo startTime và endTime của DateTime, sau đó thực hiện endTime.Subtract (startTime). Sau đó xuất ra span. Giây của bạn.

Tôi nghĩ rằng điều đó nên làm việc.


0

Tôi sử dụng năm 2000 thay vì Thời gian Kỷ nguyên trong phép tính của mình. Làm việc với số lượng nhỏ hơn dễ dàng lưu trữ và vận chuyển và thân thiện với JSON.

Năm 2000 là năm 946684800 thứ hai của kỷ nguyên.

Năm 2000 ở vị trí thứ hai 63082281600 từ ngày 1 tháng 1 năm 0001.

DateTime.UtcNow Ticks bắt đầu từ ngày 1 tháng 1 năm 0001

Giây từ năm 2000 :

DateTime.UtcNow.Ticks/10000000-63082281600

Giây từ Unix Time:

DateTime.UtcNow.Ticks/10000000-946684800

Ví dụ năm 2020 là:

var year2020 = (new DateTime ()). AddYears (2019) .Ticks; // Vì DateTime đã bắt đầu từ năm 1

637134336000000000 Bọ ve kể từ ngày 1 tháng 1 năm 0001

63713433600 Giây kể từ ngày 1 tháng 1 năm 0001

1577836800 giây kể từ Giờ kỷ nguyên

631152000 Giây kể từ năm 2000

Người giới thiệu:

Công cụ chuyển đổi Epoch Time: https://www.epochconverter.com

Bộ chuyển đổi năm 1: https://www.epochconverter.com/seconds-days-since-y0

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.