#706 常用工具汇总

2021-11-18

编辑器

  • VSCode
  • JetBrains 全家桶

SSH

数据库 GUI

Redis GUI

虚拟化与容器

  • VirtualBox
  • Vagrant
  • Docker

编程相关

  • gitg
  • Beyond Compare 可以一直试用
  • Meld Linux 下的简化版 Beyond Compare

其他

在线服务

#704 MySQL 时间相关函数汇总

2021-11-16
Name Description
ADDDATE() Add time values (intervals) to a date value
ADDTIME() Add time
CONVERT_TZ() Convert from one time zone to another
CURDATE() Return the current date
CURRENT_DATE(),
CURRENT_DATE
Synonyms for CURDATE()
CURRENT_TIME(),
CURRENT_TIME
Synonyms for CURTIME()
CURRENT_TIMESTAMP(),
CURRENT_TIMESTAMP
Synonyms for NOW()
CURTIME() Return the current time
DATE() Extract the date part of a date or datetime expression
DATE_ADD() Add time values (intervals) to a date value
DATE_FORMAT() Format date as specified
DATE_SUB() Subtract a time value (interval) from a date
DATEDIFF() Subtract two dates
DAY() Synonym for DAYOFMONTH()
DAYNAME() Return the name of the weekday
DAYOFMONTH() Return the day of the month (0-31)
DAYOFWEEK() Return the weekday index of the argument
DAYOFYEAR() Return the day of the year (1-366)
EXTRACT() Extract part of a date
FROM_DAYS() Convert a day number to a date
FROM_UNIXTIME() Format Unix timestamp as a date
GET_FORMAT() Return a date format string
HOUR() Extract the hour
LAST_DAY Return the last day of the month for the argument
LOCALTIME(),
LOCALTIME
Synonym for NOW()
LOCALTIMESTAMP,
LOCALTIMESTAMP()
Synonym for NOW()
MAKEDATE() Create a date from the year and day of year
MAKETIME() Create time from hour, minute, second
MICROSECOND() Return the microseconds from argument
MINUTE() Return the minute from the argument
MONTH() Return the month from the date passed
MONTHNAME() Return the name of the month
NOW() Return the current date and time
PERIOD_ADD() Add a period to a year-month
PERIOD_DIFF() Return the number of months between periods
QUARTER() Return the quarter from a date argument
SEC_TO_TIME() Converts seconds to 'hh:mm:ss' format
SECOND() Return the second (0-59)
STR_TO_DATE() Convert a string to a date
SUBDATE() Synonym for DATE_SUB() when invoked with three arguments
SUBTIME() Subtract times
SYSDATE() Return the time at which the function executes
TIME() Extract the time portion of the expression passed
TIME_FORMAT() Format as time
TIME_TO_SEC() Return the argument converted to seconds
TIMEDIFF() Subtract time
TIMESTAMP() With a single argument, this function returns the date or datetime expression;
with two arguments, the sum of the arguments
TIMESTAMPADD() Add an interval to a datetime expression
TIMESTAMPDIFF() Subtract an interval from a datetime expression
TO_DAYS() Return the date argument converted to days
TO_SECONDS() Return the date or datetime argument converted to seconds since Year 0
UNIX_TIMESTAMP() Return a Unix timestamp
UTC_DATE() Return the current UTC date
UTC_TIME() Return the current UTC time
UTC_TIMESTAMP() Return the current UTC date and time
WEEK() Return the week number
WEEKDAY() Return the weekday index
WEEKOFYEAR() Return the calendar week of the date (1-53)
YEAR() Return the year
YEARWEEK() Return the year and week
  • ADDDATE(date, INTERVAL expr unit), ADDDATE(expr, days)
SELECT WEEK(CURRENT_DATE());

SELECT '2021-01-01' AS `Date`, DAYNAME('2021-01-01'), DAYOFWEEK('2021-01-01'), WEEK('2021-01-01'), WEEKDAY('2021-01-01'), WEEKOFYEAR('2021-01-01'), YEARWEEK('2021-01-01')
UNION SELECT '2021-01-06' AS `Date`, DAYNAME('2021-01-04'), DAYOFWEEK('2021-01-04'), WEEK('2021-01-04'), WEEKDAY('2021-01-04'), WEEKOFYEAR('2021-01-04'), YEARWEEK('2021-01-04')
UNION SELECT '2021-01-08' AS `Date`, DAYNAME('2021-01-08'), DAYOFWEEK('2021-01-08'), WEEK('2021-01-08'), WEEKDAY('2021-01-08'), WEEKOFYEAR('2021-01-08'), YEARWEEK('2021-01-08');
-- weekday: monday 0, tuesday 1 ... sunday 6

#703 周数问题:今天是今年的第几周

2021-11-16

2021-01-01

TLDR:

  1. ISO 8601 标准:国际标准规定周一为一周的开始,包含 1 月 4 日的那一周为第一周
  2. Java: 使用 WeekFields.ISO 获取 ISO 标准周数,或使用本地化设置
  3. Python: 使用 strftime%W (本地化) 或 %V (ISO) 参数获取周数
  4. Go: 使用 ISOWeek() 方法获取 ISO 标准周数
  5. MySQL: 使用 WEEK() 函数的 mode 3 或 7 获取 ISO 标准周数

Java

import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Locale;

public class WeekNumberExample {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2021, 1, 1);
        // 使用 ISO 标准计算周数(周一为一周开始)
        int weekNumber = date.get(WeekFields.ISO.weekOfYear());
        System.out.println("ISO week number: " + weekNumber);

        // 使用本地化周数计算
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        int localizedWeek = date.get(weekFields.weekOfYear());
        System.out.println("Localized week number: " + localizedWeek);
    }
}

Python

import datetime

# 说明不同格式化参数的含义:
# %Y - 年份 (基于日历年度)
# %W - 周数 (周一作为一周的开始,第一周是包含第一个周一的周)
# %G - 年份 (基于ISO周数)
# %V - 周数 (ISO周数,周一作为一周开始,第一周是包含1月4日的那一周)

for i in range(10):
    d = datetime.date(2021 - i, 1, 1)
    print((str(d), d.weekday(), d.strftime('%Y %W / %G %V')))
('2021-01-01', 4, '2021 00 / 2020 53')
('2020-01-01', 2, '2020 00 / 2020 01')
('2019-01-01', 1, '2019 00 / 2019 01')
('2018-01-01', 0, '2018 01 / 2018 01')
('2017-01-01', 6, '2017 00 / 2016 52')
('2016-01-01', 4, '2016 00 / 2015 53')
('2015-01-01', 3, '2015 00 / 2015 01')
('2014-01-01', 2, '2014 00 / 2014 01')
('2013-01-01', 1, '2013 00 / 2013 01')
('2012-01-01', 6, '2012 00 / 2011 52')

Go

package main

import (
    "fmt"
    "time"
)

func main() {
    // Go 中计算周数
    t := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)

    // 使用 ISO 标准计算周数
    _, week := t.ISOWeek()
    fmt.Printf("ISO week number: %d\n", week)

    // 使用 YearDay 计算基于年的周数
    yearDay := t.YearDay()
    weekFromYearDay := (yearDay + 6) / 7
    fmt.Printf("Week from year day: %d\n", weekFromYearDay)
}

MySQL 中的实现

WEEK(date[, mode]) 函数:

Mode First day of week Range Week 1 is the first week …
0 Sunday 0-53 with a Sunday in this year
1 Monday 0-53 with 4 or more days this year
2 Sunday 1-53 with a Sunday in this year
3 Monday 1-53 with 4 or more days this year
4 Sunday 0-53 with 4 or more days this year
5 Monday 0-53 with a Monday in this year
6 Sunday 1-53 with 4 or more days this year
7 Monday 1-53 with a Monday in this year

总结一下,就是三个维度:

  1. 周数从 0 开始还是从 1 开始
  2. 以周一算每周的第一天还是周日
  3. 按每周第一天开始算,还是按每周四天开始算
0 周日 每周第一天 0
2 周日 每周第一天 1
4 周日 每周四天 0
6 周日 每周四天 1

1 周一 每周四天 0
3 周一 每周四天 1
5 周一 每周第一天 0
7 周一 每周第一天 1
SELECT NULL AS Mode, WEEK('2021-01-01'), WEEK('2021-01-04')
UNION SELECT 0 AS Mode, WEEK('2021-01-01', 0), WEEK('2021-01-04', 0)
UNION SELECT 1 AS Mode, WEEK('2021-01-01', 1), WEEK('2021-01-04', 1)
UNION SELECT 2 AS Mode, WEEK('2021-01-01', 2), WEEK('2021-01-04', 2)
UNION SELECT 3 AS Mode, WEEK('2021-01-01', 3), WEEK('2021-01-04', 3)
UNION SELECT 4 AS Mode, WEEK('2021-01-01', 4), WEEK('2021-01-04', 4)
UNION SELECT 5 AS Mode, WEEK('2021-01-01', 5), WEEK('2021-01-04', 5)
UNION SELECT 6 AS Mode, WEEK('2021-01-01', 6), WEEK('2021-01-04', 6)
UNION SELECT 7 AS Mode, WEEK('2021-01-01', 7), WEEK('2021-01-04', 7);
Mode WEEK('2021-01-01') WEEK('2021-01-04')
NULL 0 1
0 0 1
1 0 1
2 52 1
3 53 1
4 0 1
5 0 1
6 53 1
7 52 1

我定义的每周迭代名称(例如:2020-01A)

  1. 每周第一天为周一。
  2. 按照周一属于哪个月计算。
import datetime
from datetime import timedelta

def get_week_iteration_name(date):
    """
    根据周一所属月份计算周迭代名称
    格式:YYYY-MM{A-Z}
    返回:str, date, date (迭代名称,周一日期,周日日期)
    """
    weekday = date.weekday()
    monday = date - timedelta(days=weekday)
    sunday = monday + timedelta(days=6)

    year = monday.year
    month = monday.month

    # 计算该月第几个周一
    # 找到该月第一个周一
    first_day = datetime.date(year, month, 1)
    first_monday_offset = (7 - first_day.weekday()) % 7
    first_monday = first_day + timedelta(days=first_monday_offset)

    # 如果第一个周一不在本月,说明该月第一天就是周一
    if first_monday.month != month:
        first_monday = first_day

    # 计算是第几个周一
    week_index = ((monday - first_monday).days // 7) + 1
    # 转换为字母标识 (A=1, B=2, ...)
    week_letter = chr(ord('A') + week_index - 1)

    return f"{year}-{month:02d}{week_letter}", monday, sunday

test_dates = [
    datetime.date(2021, 1, 1),   # Friday
    datetime.date(2021, 1, 4),   # Monday
    datetime.date(2021, 1, 8),   # Friday
    datetime.date(2020, 12, 28), # Monday
]
for d in test_dates:
    weekday = d.weekday()
    name, monday, sunday = get_week_iteration_name(d)
    print(f"{d} -> {name} {weekday + 1} (Mon: {monday}, Sun: {sunday})")

#701 元宇宙与人类的未来

2021-11-15

对于近日大火的“元宇宙”概念,被称为“中国第一位元宇宙架构师”刘慈欣曾表示,元宇宙将是整个人类文明的一次内卷,而内卷的封闭系统的熵值总归是要趋于最大的。所以元宇宙最后就是引导人类走向死路一条。