2010-07-22 56 views
7

Chỉ là một câu hỏi ngẫu nhiên nhưng có ai biết công thức về cách dấu thời gian được tính toán không? Tôi đoán nó phải xem xét mỗi tháng và bao nhiêu ngày, năm nhuận, vvCông thức tính dấu thời gian là gì?

Cảm ơn

Trả lời

6

Nếu bạn là quan tâm đến việc triển khai ở đây là khoảng cách thời gian Windows có thể được tính toán (còn được gọi là ticks):

public static Int64 GetTimeStamp(
         int year, int month, int day, 
         int hour, int minute, int second, int milliseconds) 
{ 
    Int64 timestamp = DateToTicks(year, month, day) 
     + TimeToTicks(hour, minute, second); 

    return timestamp + milliseconds * TicksInMillisecond; 
} 

static readonly int[] DaysToMonth365 = 
    new int[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; 
static readonly int[] DaysToMonth366 = 
    new int[] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; 
const long TicksInSecond = TicksInMillisecond * 1000L; 
const long TicksInMillisecond = 10000L; 

public static bool IsLeapYear(int year) 
{ 
    if ((year < 1) || (year > 9999)) 
     throw new ArgumentOutOfRangeException("year", "Bad year."); 

    if ((year % 4) != 0) 
     return false; 

    if ((year % 100) == 0) 
     return ((year % 400) == 0); 

    return true; 
} 

private static long DateToTicks(int year, int month, int day) 
{ 
    if (((year >= 1) && (year <= 9999)) && ((month >= 1) && (month <= 12))) 
    { 
     int[] daysToMonth = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365; 
     if ((day >= 1) && (day <= (daysToMonth[month] - daysToMonth[month - 1]))) 
     { 
      int previousYear = year - 1; 
      int daysInPreviousYears = ((((previousYear * 365) + (previousYear/4)) - (previousYear/100)) + (previousYear/400)); 

      int totalDays = ((daysInPreviousYears + daysToMonth[month - 1]) + day) - 1; 
      return (totalDays * 0xc92a69c000L); 
     } 
    } 
    throw new ArgumentOutOfRangeException(); 
} 

private static long TimeToTicks(int hour, int minute, int second) 
{ 
    long totalSeconds = ((hour * 3600L) + (minute * 60L)) + second; 
    if ((totalSeconds > 0xd6bf94d5e5L) || (totalSeconds < -922337203685L)) 
     throw new ArgumentOutOfRangeException(); 

    return (totalSeconds * TicksInSecond); 
} 
+0

Tôi muốn viết điều này bằng PHP. – David

+1

@David: Các hàm 'time' và' gmmktime' của PHP trả về các dấu thời gian của Unix. Nếu bạn muốn, bạn có thể chuyển đổi nó thành các dấu tích là '621355968000000000 + unixTimestamp * 10000000' – Regent

+0

0xd6bf94d5e5L, 0xc92a69c000L và 922337203685L là gì? –

1

Thông thường nó là thời gian trôi qua kể từ khi một ngày cụ thể. Trong trường hợp của thời gian unix, đó là thời gian trôi qua kể từ ngày 1 tháng 1 năm 1970 trong vài giây.

6

Dưới đây là một ví dụ về cách Unix timestamp được tính từ wikipedia article:

Số lần Unix là zero tại Unix kỷ nguyên , và tăng chính xác 86 400 mỗi ngày kể từ khi kỷ nguyên. Do đó 2004-09-16T00: 00: 00Z, 12 677 ngày sau kỷ nguyên, được đại diện bởi Số thời gian Unix 12 677 × 86 400 = 1 095 292 800. Điều này có thể được mở rộng ngược từ kỷ nguyên quá , sử dụng số số âm; do đó 1957-10-04T00: 00: 00Z, 4 472 ngày trước thời đại, được đại diện bởi số thời gian Unix -4 472 × 86 400 = -386 380 800.

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