公历转农历的脚本,可用于conky

sh/bash/dash/ksh/zsh等Shell脚本
头像
c\nc
帖子: 231
注册时间: 2007-12-25 12:51

公历转农历的脚本,可用于conky

#1

帖子 c\nc » 2010-03-05 13:53

原版在这里:
http://www.lihuasoft.net/article/show.php?id=797

原版有注释,所以我翻译的山寨版就省了 :em04 ,其实很简单,就是查表。

代码: 全选

#!/bin/bash
DOM=(0xd4a8 0xd4a0 0xda50 0x5aa8 0x56a0 0xaad8 0x25d0 0x92d0 0xc958 0xa950 
	 0xb4a0 0xb550 0xb550 0x55a8 0x4ba0 0xa5b0 0x52b8 0x52b0 0xa930 0x74a8
	 0x6aa0 0xad50 0x4da8 0x4b60 0x9570 0xa4e0 0xd260 0xe930 0xd530 0x5aa0
	 0x6b50 0x96d0 0x4ae8 0x4ad0 0xa4d0 0xd258 0xd250 0xd520 0xdaa0 0xb5a0
	 0x56d0 0x4ad8 0x49b0 0xa4b8 0xa4b0 0xaa50 0xb528 0x6d20 0xada0 0x55b0)
LMOY=(0x40 0x02 0x07 0x00 0x50
	  0x04 0x09 0x00 0x60 0x04
	  0x00 0x20 0x60 0x05 0x00
	  0x30 0xb0 0x06 0x00 0x50
	  0x02 0x07 0x00 0x50 0x03)
START=2001; END=2050
# $1: 2001-2050
get_leap_month()
{
	sft=$(( $1 - $START )); dom=${LMOY[$(( $sft >> 1 ))]}
	echo $(( $(( sft & 1 ))?$(( $dom & 0x0f )):$(( $dom >> 4 )) ))
}
# $1: 2001-2050, $2: 1-12
get_days_of_month()
{
	y=$1; m=$2; high=0; low=29; sft=$(( 16 - $m ))
	dom=${DOM[$(( $y - $START ))]}; lmoy=$(get_leap_month $y)
	[ $m -gt $lmoy -a $lmoy -gt 0 ] && let "sft--"
	[ $(( $dom & $(( 1 << $sft )) )) -gt 0 ] && let "low++"
	if [ $m -eq $lmoy ]; then
		let "sft--"
		high=$(( $(( $dom & ( 1 << $sft ) ))?30:29 ))
	fi
	echo $(( low + ( high << 16) ))
}
# $1: 2001-2050
get_days_of_year()
{
	y=$1; d=0
	for i in {1..12}; do
		tmp=$(get_days_of_month $y $i)
		let "d+=$(( $(( $tmp >> 16)) & 0xffff ))"
		let "d+=$(( $tmp & 0xffff ))"
	done
	echo $d
}
#
parse_year()
{
	HS="甲乙丙丁戊己庚辛壬癸"; EB="子丑寅卯辰巳午未申酉戌亥"
	echo "${HS:$(( ($1 - 4) % 10 )):1}${EB:$(( ($1 - 4) % 12 )):1}"
}	
#
parse_month()
{
	LM=('' '正' '二' '三' '四' '五' '六' '七' '八' '九' '十' '十一' '十二')
	echo "${LM[$1]}"
}
#
parse_day()
{
	PREFIX="初十廿"; DAY="一二三四五六七八九十"
	d=$1
	if [ $d -eq 20 ]; then
		echo "二十"
	elif [ $d -eq 30 ]; then
		echo "三十"
	else
		echo "${PREFIX:$(( ($d - 1) / 10 )):1}${DAY:$(( ($d - 1) % 10 )):1}"
	fi
}
parse_date()
{
	d=${*:-$(date)}; leap=
	sft=$(( ( $(date -d "$d" +%s) - $(date -d "${START}/01/01" +%s) ) / 60 / 60 / 24 ))
	if [ $sft -lt 23 ]; then
		ly=2000
		lm=12
		ld=$(( $sft + 7 ))
	else
		let "sft-=23"; ly=2001; lm=1; ld=1
		tmp=$(get_days_of_year $ly)
		while [ $sft -ge $tmp ]; do
			let "sft-=$tmp"
			let "ly++"
			tmp=$(get_days_of_year $ly)
		done
		tmp=$(( $(get_days_of_month $ly $lm) & 0xffff ))
		while [ $sft -ge $tmp ]; do
			let "sft-=$tmp"
			if [ $lm -eq $(get_leap_month $ly) ]; then
				tmp=$(( $(get_days_of_month $ly $lm) >> 16 ))
				if [ $sft -lt $tmp ]; then
					test $tmp -gt 0 && leap="闰"
					break
				fi
				let "sft-=$tmp"
			fi
			let "lm++"
			tmp=$(( $(get_days_of_month $ly $lm) & 0xffff ))
		done
		let "ld+=$sft"
	fi
	echo "$(parse_year $ly)年${leap}$(parse_month $lm)月$(parse_day $ld)"
}
parse_date "$*"
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 公历转农历的脚本,可用于conky

#3

帖子 eexpress » 2010-03-05 15:39

这事情,也只能查表。
:em04
● 鸣学
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
联系:

Re: 公历转农历的脚本,可用于conky

#4

帖子 DerekTan » 2010-03-05 16:01

我都不知道公历转农历是怎么样的规则……有人知道不?
头像
fengjie
帖子: 130
注册时间: 2008-03-19 14:20

Re: 公历转农历的脚本,可用于conky

#5

帖子 fengjie » 2010-03-15 11:30

不错,大哥翻译水品太牛了
主板:ASUS P8Z77-V
CPU:Intel 酷睿i3 3200
内存:ADTA DDRⅢ 1600 8G
显卡:Intel® HD Graphic
声卡:Realtek ALC 892
有线网卡:Intel® 82579V
无线网卡:Qualcomm Atheros AR9485
硬盘:WDC WD6401AALS
电源:长城ATX-350SD静音大师
显示器:Samsung S24A350H
头像
tenzu
论坛版主
帖子: 36924
注册时间: 2008-11-21 20:26

Re: 公历转农历的脚本,可用于conky

#6

帖子 tenzu » 2010-03-15 11:33

召唤慧慧
JiangHui
论坛版主
帖子: 21308
注册时间: 2007-08-02 20:29
系统: 窓辺とうこ

Re: 公历转农历的脚本,可用于conky

#7

帖子 JiangHui » 2010-03-15 11:33

虾米事?
头像
tenzu
论坛版主
帖子: 36924
注册时间: 2008-11-21 20:26

Re: 公历转农历的脚本,可用于conky

#8

帖子 tenzu » 2010-03-15 11:34

记得你发过一个
t3swing
帖子: 1028
注册时间: 2008-11-01 21:42
来自: 树下板凳

Re: 公历转农历的脚本,可用于conky

#9

帖子 t3swing » 2010-03-15 16:48

很多万年历都是这种东西,想查查毛嗲嗲的诞辰都查不到 .
有没有真正意义上的万年历 ?至少不能只有一百年 ,找了好久,都只看到只能查询百年的伪万年历源码
我都不知道公历转农历是怎么样的规则……有人知道不?
估计难 ,规律强的话,用不着查表吧,真万年历也不至于那么难找

lz翻译水平不错
民族的脊梁,是踏实做事的人,非只知道骂街的泼妇。
头像
rapistor
帖子: 1983
注册时间: 2009-01-19 15:09

Re: 公历转农历的脚本,可用于conky

#10

帖子 rapistor » 2010-03-15 18:22

农历和阳历每十九年重合一次,所以你只要知道任何一种日期,用这个方法就能找到相对应的日期了。
坚守在linux的天堂!
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 公历转农历的脚本,可用于conky

#11

帖子 aerofox » 2010-03-23 0:35

有一个命令 lunar 可以完成公农历转换。
rapistor 写了:农历和阳历每十九年重合一次,所以你只要知道任何一种日期,用这个方法就能找到相对应的日期了。
十九年只是大致的重合,就不说农历的复杂的置闰月的算法,单从公历来说,不考虑 400 年的问题,也是 4 年一重复周期,19 不是 4 的倍数,所以农历和阳历每十九年重合一次是不准确的。2008 年有 2 月 29 日,可是 2027 年呢?
t3swing
帖子: 1028
注册时间: 2008-11-01 21:42
来自: 树下板凳

Re: 公历转农历的脚本,可用于conky

#12

帖子 t3swing » 2010-03-23 8:41

同意ls的 ,不然也不会用查表的方法搞 ,学习一下lunar命令是咋整出来的
民族的脊梁,是踏实做事的人,非只知道骂街的泼妇。
头像
bones7456
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
联系:

Re: 公历转农历的脚本,可用于conky

#13

帖子 bones7456 » 2010-03-23 10:31

看图~~
附件
lunar
lunar
screenshot3.png (47.69 KiB) 查看 4777 次
关注我的blog: ε==3
t3swing
帖子: 1028
注册时间: 2008-11-01 21:42
来自: 树下板凳

Re: 公历转农历的脚本,可用于conky

#14

帖子 t3swing » 2010-03-23 12:33

sw@~$lunar -h --utf8 1893 12 26
Lunar Version 2.2 (October 28, 2001)

Year out of range.
sw@~$lunar -h --utf8 2010 3 23
Lunar Version 2.2 (October 28, 2001)

阳历: 2010年 3月23日 0时 星期二
阴历: 2010年 2月 8日子时 生肖属虎
干支: 庚寅年 己卯月 壬申日 庚子时 
用四柱神算推算之时辰八字: 庚寅年 己卯月 壬申日 庚子时 
sw@~$
也是150年的伪万年历!悲剧了
民族的脊梁,是踏实做事的人,非只知道骂街的泼妇。
头像
zhousm
帖子: 122
注册时间: 2010-03-12 13:20
系统: ubuntu 14.04 LTS
来自: 湘潭

Re: 公历转农历的脚本,可用于conky

#15

帖子 zhousm » 2010-11-21 11:03

楼主强悍, :em11
ubuntu 14.04 LTS
回复