我怎樣才能從一個unix時間戳,以數學的方式,並沒有使用任何功能和簡單的數學公式計算天數。以數學方式從unix-timestamp計算天數?
1313905026 - > 8(今天2011年8月21日)
我怎樣才能從一個unix時間戳,以數學的方式,並沒有使用任何功能和簡單的數學公式計算天數。以數學方式從unix-timestamp計算天數?
1313905026 - > 8(今天2011年8月21日)
沒有簡單的公式來做到這一點。你將需要減去自紀元以來的年數(佔閏年),這可能需要循環或某種離散計算。然後使用某種類型的循環來減去當年每月的秒數。剩下的是當前進入月份的秒數。
我會做這樣的事情。
x = ...//the number of seconds
year = 1970
while (x > /*one year*/){
x = x - /*seconds in january, and march-december*/
if(year % 4 == 0){
x -= /*leapeay seconds in february*/
}else{
x -= /*regular seconds in february*/
}
}
//Then something like this:
if(x > /*seconds in january*/){
x -= /*seconds in january*/
}
if(x > /*seconds in february*/){
x -= /*seconds in january*/
}
.
.
.
//After that just get the number of days from x seconds and you're set.
編輯
我建議使用最新功能簡單,但這裏是萬一有人可能不糊塗的備選答案需要它,還是會在意進一步發展它。
首先讓t爲從曆元開始的秒數。
設F是四年內的秒數。那是三年和一年閏年。那應該是:126230400.
現在如果你拿走F所貢獻的所有時間,你將得到一個餘數:y。
所以Y = N%F
有幾種情況現在: 1,y是不太有一年 2. y是不到兩年 3 y是不到三年的時間少兩個多月 4 y是不到三年的時間和更大的兩個多月 5 y是不到四年
注意,1972年是閏年,所以如果你從1970年,無論你計數四離開將是兩年的閏年。
讓jan,feb,febLY,mar,may,... dec分別爲每月的秒數(您需要計算出來)。
d代表當前月份的日期編號,D代表一天中的秒數(86400)。 y表示常規年份中的秒數,yLY表示閏年中的秒數。
y = (t % F)
if(y < Y){
if(y > jan){
y -= jan
}
if(y > feb){
y -= feb
}
.
.
.
d = y % D
}
else if(y < 2 * y){
y = y - Y
if(y > jan){
y -= jan
}
if(y > feb){
y -= feb
}
.
.
.
d = y % D
}
else if(y < 2 * y + yLY){
y = y - 2 * Y
if(y > jan){
y -= jan
}
if(y > febLY){
y -= febLY
}
.
.
.
d = y % D
}
else{
y = y - 2 * Y - yLY
if(y > jan){
y -= jan
}
if(y > feb){
y -= feb
}
.
.
.
d = y % D
}
未測試。另外,由於地球不會在1圈/ 24小時旋轉,所以偶爾會對時間進行調整。你需要做一些研究的因素是,在
t = unix time
second = t MOD 60
minute = INT(t/60) MOD 60
hour = INT(t/60/60) MOD 24
days = INT(t/60/60/24)
years = INT(days/365.25)
year = 1970 + years + 1
1970年開始與週四的話,我們可以計算出星期幾。
weekday = (days + 4) MOD 7
如果星期天是0天,如果您想要星期天是第1天,只需加1。
現在,讓我們來看看我們在這一年有多少天。
days = days - years * 365 - leapdays
最後,我們找到月份的月份和日期。
IF year MOD 4 = 0 THEN ly = 1 ELSE ly = 0
WHILE month <= 12
month = month + 1
IF month = 2 THEN
DaysInMonth = 28 + NOT(year MOD 4) + NOT(year MOD 100)
+ NOT(year MOD 400)
ELSE
DaysInMonth = 30 + (month + (month < 7)) MOD 2
END IF
IF days > DaysInMonth THEN days = days - DaysInMonth
END WHILE
這是假設的TRUE = 1,FALSE = 0,不是真的= 0,沒有虛假記載,布爾值= 1
現在我們有一個月,小時的年,月,日,分鐘,第二次計算閏年調整。
A unix timestamp不包括leap seconds,所以我們不必擔心這一點。下面是一個分支少,用於從unix timestamp得到Y/M/d域環路少的算法:
#include <iostream>
int
main()
{
int s = 1313905026;
int z = s/86400 + 719468;
int era = (z >= 0 ? z : z - 146096)/146097;
unsigned doe = static_cast<unsigned>(z - era * 146097);
unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096)/365;
int y = static_cast<int>(yoe) + era * 400;
unsigned doy = doe - (365*yoe + yoe/4 - yoe/100);
unsigned mp = (5*doy + 2)/153;
unsigned d = doy - (153*mp+2)/5 + 1;
unsigned m = mp + (mp < 10 ? 3 : -9);
y += (m <= 2);
std::cout << m << '/' << d << '/' << y << '\n'; // 8/21/2011
}
此輸出:
8/21/2011
當你不感興趣在y
和m
(只在d
),你可以從上面的計算中消除最後幾行。
該算法在極其詳細的描述here中描述。鏈接包括一個完整的推導,以及跨越數百萬年的單元測試(這是過度殺傷)。
科少:是什麼樣子的算法小樹枝上面在-O3在MacOS優化掉的鏗鏘:
__Z14get_day_numberi: ## @_Z14get_day_numberi
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
movslq %edi, %rax
imulq $-1037155065, %rax, %rcx ## imm = 0xFFFFFFFFC22E4507
shrq $32, %rcx
addl %ecx, %eax
movl %eax, %ecx
shrl $31, %ecx
sarl $16, %eax
leal (%rax,%rcx), %edx
leal 719468(%rax,%rcx), %esi
testl %esi, %esi
leal 573372(%rax,%rcx), %eax
cmovnsl %esi, %eax
cltq
imulq $963315389, %rax, %rcx ## imm = 0x396B06BD
movq %rcx, %rsi
shrq $63, %rsi
shrq $32, %rcx
sarl $15, %ecx
addl %esi, %ecx
imull $146097, %ecx, %ecx ## imm = 0x23AB1
movl %eax, %esi
subl %ecx, %esi
subl %eax, %esi
leal 719468(%rsi,%rdx), %eax
movl %eax, %ecx
shrl $2, %ecx
imulq $1506180313, %rcx, %rdx ## imm = 0x59C67CD9
shrq $39, %rdx
movl %eax, %esi
subl %edx, %esi
imulq $963321983, %rcx, %rcx ## imm = 0x396B207F
shrq $43, %rcx
addl %esi, %ecx
movl %eax, %edx
shrl $4, %edx
imulq $7525953, %rdx, %rdx ## imm = 0x72D641
shrq $36, %rdx
subl %edx, %ecx
imulq $1729753953, %rcx, %rsi ## imm = 0x6719F361
shrq $32, %rsi
movl %ecx, %r8d
subl %ecx, %eax
movl %ecx, %edi
movl $3855821599, %edx ## imm = 0xE5D32B1F
imulq %rcx, %rdx
subl %esi, %ecx
shrl %ecx
addl %esi, %ecx
shrl $8, %ecx
imull $365, %ecx, %ecx ## imm = 0x16D
subl %ecx, %r8d
shrl $2, %edi
imulq $1506180313, %rdi, %rcx ## imm = 0x59C67CD9
shrq $39, %rcx
shrq $47, %rdx
addl %r8d, %eax
subl %ecx, %eax
leal (%rax,%rdx), %ecx
leal 2(%rcx,%rcx,4), %esi
movl $3593175255, %edi ## imm = 0xD62B80D7
imulq %rsi, %rdi
shrq $39, %rdi
imull $153, %edi, %edi
subl %edi, %esi
leal 4(%rcx,%rcx,4), %ecx
subl %esi, %ecx
movl $3435973837, %esi ## imm = 0xCCCCCCCD
imulq %rcx, %rsi
shrq $34, %rsi
leal 1(%rax,%rdx), %eax
subl %esi, %eax
popq %rbp
retq
.cfi_endproc
+1對於鏈接背後令人難以解釋的解釋:http://howardhinnant.github.io/date_algorithms.html#civil_from_days – Semo
謝謝你,所以我認爲它能夠更好地計算它使用DATE函數,因爲我想把它放在sql查詢的中間。 –
等一下,我明白了!請稍等,我會在上面發表我的回答。 – JSideris