Hàm tạo dấu thời gian trong c #


101

Tôi đã tự hỏi, có cách nào để tạo dấu thời gian trong c # từ ngày giờ không? Tôi cần giá trị chính xác mili giây cũng hoạt động trong Compact Framework (nói rằng vì DateTime.ToBinary () không tồn tại trong CF).

Vấn đề của tôi là tôi muốn lưu trữ giá trị này theo cách bất khả tri cơ sở dữ liệu để tôi có thể sắp xếp nó sau này và tìm ra giá trị nào lớn hơn từ giá trị khác, v.v.


2
Câu trả lời được chấp nhận ở đây đưa ra một giải pháp hay, nhưng nếu bạn muốn có dấu thời gian thực, hãy xem phần Hỏi / Đáp này: stackoverflow.com/questions/9814060/…
inanutshellus 3/12/12

Câu trả lời:


206

Tôi luôn sử dụng một cái gì đó như sau:

public static String GetTimestamp(this DateTime value)
{
    return value.ToString("yyyyMMddHHmmssfff");
}

Điều này sẽ cung cấp cho bạn một chuỗi như 200905211035131468, vì chuỗi đi từ bit thứ tự cao nhất của dấu thời gian đến thứ tự thấp nhất. Sắp xếp chuỗi đơn giản trong truy vấn SQL của bạn có thể được sử dụng để sắp xếp theo ngày nếu bạn đang gắn các giá trị trong cơ sở dữ liệu


5
Tại sao bạn có 21 tháng và chỉ có 12? :)
PaulB

2
Mã thông báo cho năm phải là chữ thường ở đây: return value.ToString ("yyyyMMddHHmmssffff");
Don Cote

1
@RobV Câu hỏi yêu cầu độ chính xác mili giây, vì vậy bạn cần 3 'f ở cuối. 4 'f của bạn cho độ chính xác 100 microsend.
Eugene Beresovsky

2
Hãy lưu ý, Khung nhỏ gọn đó không chuyển mili giây. Chúng sẽ luôn bằng 0. Bạn phải sửa đổi mã và thêm một số thứ như sau: int tick = Environment.TickCount% 1000; int ms = (đánh dấu> = MOffset)? (đánh dấu - MOffset): (1000 - (MOffset - đánh dấu)); ms = Math.Min (999, Math.Max ​​(0, ms));
Redwolf

43

Tôi tin rằng bạn có thể tạo dấu dữ liệu kiểu unix chính xác đến từng giây bằng cách sử dụng

//Find unix timestamp (seconds since 01/01/1970)
long ticks = DateTime.UtcNow.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks;
ticks /= 10000000; //Convert windows ticks to seconds
timestamp = ticks.ToString();

Điều chỉnh mẫu số cho phép bạn chọn mức độ chính xác của mình


19

Bạn có thể sử dụng thuộc tính DateTime.Ticks, đây là một bộ lưu trữ lâu dài và phổ biến, luôn tăng và có thể sử dụng được trên khung nhỏ gọn. Chỉ cần đảm bảo mã của bạn không được sử dụng sau ngày 31 tháng 12 năm 9999;)


Tuy nhiên, khi bạn nói "luôn tăng" - không có gì đảm bảo rằng hai lệnh gọi đến DateTime.UtcNow.Ticks sẽ cung cấp các giá trị khác nhau, phải không? Nói cách khác, bạn vẫn cần thận trọng trước khi sử dụng nó như một dấu thời gian duy nhất.
Jon Skeet

9
@Konstantinos: bạn không thể tránh trùng lặp nếu bạn sử dụng dấu thời gian. Dấu thời gian không được sử dụng cho các phím duy nhất mà để đánh dấu thời gian. Bạn đã nói rằng bạn cần độ chính xác mili giây và bọ ve có độ chính xác 100ns. Vấn đề là bạn sẽ có các bản sao. Nếu bạn không muốn, bạn cần một chuỗi duy nhất trong DB, điều này rất tiếc không phải là bất khả tri db.
Frans Bouma

3
"đó là số lượng đánh dấu thực tăng theo thời gian". Nhưng đồng hồ hệ thống có thể quay ngược lại - ví dụ: vào cuối giờ tiết kiệm ánh sáng ban ngày nếu bạn đang sử dụng giờ địa phương hoặc do đồng hồ hệ thống đã được điều chỉnh.
Joe

1
@Frans: hoàn toàn. Tôi chỉ đưa ra nhận xét vì mọi người nên suy nghĩ về hàm ý của giải pháp họ chọn. Ví dụ: tôi sẽ sử dụng UTC thay vì giờ địa phương để ít nhất loại bỏ các vấn đề của DST.
Joe

1
@konstantinos: hmm ... các tài liệu nói rằng nó có độ chính xác 100ns, vì vậy thật kỳ lạ khi nó không có độ chính xác như được ghi lại. Có lẽ đó thực sự là khung công tác nhỏ gọn, nó không phải là một khung công tác không có lỗi
Frans Bouma

6

Bạn cũng có thể dùng

Đồng hồ bấm giờ.GetTimestamp (). ToString ();


4

khi bạn cần dấu thời gian tính bằng giây, bạn có thể sử dụng như sau:

var timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;

2

Nếu bạn muốn dấu thời gian tương ứng với thời gian thực thực tế NHƯNG cũng muốn chúng là duy nhất (đối với một phiên bản ứng dụng nhất định), bạn có thể sử dụng mã sau:

public class HiResDateTime
{
   private static long lastTimeStamp = DateTime.UtcNow.Ticks;
   public static long UtcNowTicks
   {
       get
       {
           long orig, newval;
           do
           {
               orig = lastTimeStamp;
               long now = DateTime.UtcNow.Ticks;
               newval = Math.Max(now, orig + 1);
           } while (Interlocked.CompareExchange
                        (ref lastTimeStamp, newval, orig) != orig);

           return newval;
       }
   }
}
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.