Math 用数学方法从unix时间戳计算天数?

Math 用数学方法从unix时间戳计算天数?,math,datetime,date,unix-timestamp,Math,Datetime,Date,Unix Timestamp,如何从unix时间戳以数学方式计算日数,而不使用任何函数和简单的数学公式 1313905026-->8(今天是2011年8月21日)没有简单的公式可以做到这一点。您需要减去自新纪元以来的年数(考虑闰年),这可能需要一个循环或某种离散计算。然后使用某种类型的循环减去当前年份每个月的秒数。剩下的是当月的秒数 我会这样做 x=…//秒数 年份=1970年 而(x>/*一年*/){ 1月和3月至12月的x=x-/*秒*/ 如果(第%4年==0){ 2月份的每秒钟x-=/*跳跃*/ }否则{ 二月的x-=

如何从unix时间戳以数学方式计算日数,而不使用任何函数和简单的数学公式


1313905026-->8(今天是2011年8月21日)

没有简单的公式可以做到这一点。您需要减去自新纪元以来的年数(考虑闰年),这可能需要一个循环或某种离散计算。然后使用某种类型的循环减去当前年份每个月的秒数。剩下的是当月的秒数

我会这样做

x=…//秒数
年份=1970年
而(x>/*一年*/){
1月和3月至12月的x=x-/*秒*/
如果(第%4年==0){
2月份的每秒钟x-=/*跳跃*/
}否则{
二月的x-=/*常规秒数*/
}
}
//然后像这样:
如果(1月x>/*秒*/){
一月份的x-=/*秒*/
}
如果(2月x>/*秒*/){
一月份的x-=/*秒*/
}
.
.
.
//之后,只需从x秒开始计算天数,即可设置。
编辑

为了简单起见,我建议使用日期函数,但这里有一个可能的非循环替代答案,以防任何人需要它,或者希望进一步开发它

首先,t是自纪元以来的当前时间(以秒为单位)

设F为四年内的秒数。这是三个正常年份和一个闰年。这应该是:126230400

现在,如果你去掉F贡献的所有时间,你会得到一个余数:y

所以y=n%F

现在有几种情况: 1.y小于一年 2.y不到两年 3.y不到三年也不到两个月 4.y小于三年,大于两个月 5.y不到四年

请注意,1972年是闰年,所以如果你从1970年算起,再加上4年,无论你在哪里停下来,都将是两年后的闰年

让一月,二月,费布莱,三月,五月,…,十二月是每个月的秒数(你需要计算出来)

d表示当前月份的天数,d表示一天中的秒数(86400)。 y表示正常年份的秒数,yLY表示闰年的秒数

y=(t%F)
if(y1月){
y-=一月
}
如果(y>2月){
y-=feb
}
.
.
.
d=y%d
}
否则如果(y<2*y){
y=y-y
如果(y>1月){
y-=一月
}
如果(y>2月){
y-=feb
}
.
.
.
d=y%d
}
否则如果(y<2*y+yLY){
y=y-2*y
如果(y>1月){
y-=一月
}
如果(y>febLY){
y-=febLY
}
.
.
.
d=y%d
}
否则{
y=y-2*y-yLY
如果(y>1月){
y-=一月
}
如果(y>2月){
y-=feb
}
.
.
.
d=y%d
}
没有测试。此外,由于地球并不是以每24小时1圈的速度自转,他们偶尔会调整时间。你需要在这方面做一些研究

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

现在,让我们来看看我们进入这一年的天数

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
如果年份MOD 4=0,则ly=1,否则ly=0
而月份DaysInMonth则days=天-DaysInMonth
结束时
这假定布尔值为TRUE=1、FALSE=0、NOT TRUE=0和NOT FALSE=1

现在我们已经计算了年、月、月日、小时、分钟和秒,并对闰年进行了调整。

A不包括在内,所以我们不必担心这一点。下面是一个无分支、无循环的算法,用于从a获取y/m/d字段:

由于您对
y
m
(仅在
d
中)不感兴趣,因此可以从上述计算中删除最后几行

这个算法描述得非常详细。该链接包括一个完整的派生,以及跨越数百万年的单元测试(这太过分了)


1分支减少:在macOS上,通过在-O3上发出叮当声来优化上述算法中的小分支:

__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
锈迹斑斑:

fn date(mut months_to_shift: i32, timezone_shift: i32) -> String {
    months_to_shift = months_to_shift * 2_628_000;

    let timestamp = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .expect("Before time!")
    .as_secs() as f32;

    let adjusted_time = ((((timestamp / 31_557_600.0) / 4.0).round() as i32 * 86_400)
        + 604800
        + (timezone_shift * 3600)
        + months_to_shift) as f32
        + timestamp; // 608400 offset for number of days missing - 7 - (???) + leap year days +/- timezone shift from EST -- Using timezone shift in my project but not necessary

    let years = (1970.0 + (adjusted_time / 31_536_000.0)) as i32;

    let mut months = ((adjusted_time % 31_536_000.0) / 2_628_000.0) as i32;
    months = if months == 0 { 12 } else { months };

    let days = ((adjusted_time % 2_628_000.0) / 86_400.0) as i32;

    years.to_string() + "-" + &months.to_string() + "-" + &days.to_string()
}

谢谢,所以我认为最好使用日期函数来计算它,因为我想把它放在sql查询的中间!请稍等,我将在上面发布我的答案。+1链接背后令人痛苦的解释:这个常数不是比
365.25
更多吗?
__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
fn date(mut months_to_shift: i32, timezone_shift: i32) -> String {
    months_to_shift = months_to_shift * 2_628_000;

    let timestamp = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .expect("Before time!")
    .as_secs() as f32;

    let adjusted_time = ((((timestamp / 31_557_600.0) / 4.0).round() as i32 * 86_400)
        + 604800
        + (timezone_shift * 3600)
        + months_to_shift) as f32
        + timestamp; // 608400 offset for number of days missing - 7 - (???) + leap year days +/- timezone shift from EST -- Using timezone shift in my project but not necessary

    let years = (1970.0 + (adjusted_time / 31_536_000.0)) as i32;

    let mut months = ((adjusted_time % 31_536_000.0) / 2_628_000.0) as i32;
    months = if months == 0 { 12 } else { months };

    let days = ((adjusted_time % 2_628_000.0) / 86_400.0) as i32;

    years.to_string() + "-" + &months.to_string() + "-" + &days.to_string()
}