以下文章參考出處:.NET 非對稱式加密與數位簽章程式設計入門
簡介
這裡不打算講太多加解密的原理,我想,對這篇文章有興趣的人,對於雜湊演算法(hashing algorithm,如:SHA-1)、對稱式加密(如:DES、AES)、非對稱式加密(如:RSA 演算法)、公開金鑰(public key)、私密金鑰(private key)等應該多少都有一點概念吧。當然,在說明程式如何實作之前,還是會帶到一些關鍵的概念與原理,否則光看程式碼而不知其所以然,等到實際應用時恐怕還是不知從何著手。
基本上,數位簽章是基於非對稱式加密的技術,而目前較常用的非對稱式加密方法,則是 RSA 演算法。就實務面的應用而言,你可以不用了解非對稱式加密技術是怎麼來的,但至少要知道以下規則:
1. 私密金鑰必須妥善保存,絕不可外洩;公開金鑰可對外公開,任何人都能取得。
2. 使用公開金鑰加密的資料只有對應的私鑰可解,使用私密金鑰加密的資料只有對應的公開金鑰能解。
基於上述特性,非對稱式加密方法非常適合用於許多需要加密和驗證資料完整性的場合。比如說,Alice 想要寫一封情書給隔壁班的 Bob,並拜託中間人 Eve 轉交給他,可是 Alice 擔心 Eve 會偷看情書的內容,此時她就可以將情書內容用 Bob 的公開金鑰(以下簡稱公鑰)加密;基於前述第 2 項特性,因此只有 Bob 能夠用他的私密金鑰(以下簡稱私鑰)解密。由於 Eve 沒有 Alice 的私密金鑰,因此她無法窺得原文,而且,就算 Eve 花再多時間,也很難在有生之年解開這段密文。
接著就來看看如何使用 .NET Framework 提供的類別實作非對稱式加密和解密。
註:在舉例說明加解密的應用情境時,經常會看到 Alice 和 Bob 這兩個人名,這已經成了慣例。
使用公鑰加密,私鑰解密
.NET Framework 提供的加解密類別全都放在 System.Security.Cryptography 命名空間裡,因此以下的範例程式都必須引用此命名空間。以下示範以 RSA 演算法來實作非對稱式加解密:
1 // 建立 RSA 加解密物件。
2 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
3
4 // 欲加密的原文。
5 string orgText = "Hello, 密碼學!";
6
7 // 加密。
8 byte[] orgData = Encoding.Default.GetBytes(orgText);
9 byte[] encryptedData = rsa.Encrypt(orgData, false);
10
11 // 解密。
12 byte[] decryptedData = rsa.Decrypt(encryptedData, false);
13 string decryptedText = Encoding.Default.GetString(decryptedData);
這段範例是把加密和解密的動作一次做完,當然實際上並不會這樣寫,通常是先將資料加密之後,傳送至目標,目標在收到密文之後才做解密的動作。這裡只是為了讓程式儘可能簡單,並且讓你一次看到全貌。
注意範例程式中的第 2 行,它會建立一個 RSACryptoServiceProvider 的物件,而且在建立物件時,就已經產生一對公鑰跟私鑰,在後續的加解密動作時,就是直接使用這對金鑰,因此你不會覺得需要對公鑰私鑰做什麼特別的處理。不過,當你將加密和解密的動作拆開時,就會碰到傳遞金鑰的問題。你可以想像一下,Alice 若要將密文傳給 Bob,而且希望只有 Bob 能看解開,她就必須使用 Bob 的公開金鑰來加密。因此在實作時,程式必須先產生 Bob 的金鑰,並將公鑰儲存在可任意存取的地方,以便加密時使用。
接著就來修改前面的範例,把加密和解密動作拆開。首先,在 Visual Studio 2005 中建立一個 Windows Forms 專案,然後在 form 上面放兩個 TextBox 和兩個 Button,其個別命名與用途如下:
* btnEncrypt:執行加密動作的按鈕。
* btnDecrypt:執行解密動作的按鈕。
* txtEncrypted:用來顯示加密的結果。
* txtDecrypted:用來顯示解密的結果。
我們需要先建立接收者的金鑰,這個動作就放在 form1 的 Load 事件中完成,而 btnEncrypt 和 btnDecrypt 按鈕的事件處理程序則分別處理資料的加密和解密。以下是修改後的完整原始碼:
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8 using System.Security.Cryptography;
9
10 namespace AsymmetricEncryptionDemo
11 {
12 public partial class Form1 : Form
13 {
14 public string bobPrivateKey;
15 public string bobPublicKey;
16
17
18 private void Form1_Load(object sender, EventArgs e)
19 {
20 // 產生 Bob 的金鑰對。
21 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
22 bobPrivateKey = rsa.ToXmlString(true);
23 bobPublicKey = rsa.ToXmlString(false);
24 }
25
26 private void btnEncrypt_Click(object sender, EventArgs e)
27 {
28 // 建立 RSA 加解密物件。
29 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
30
31 // 匯入公開金鑰(因為要使用接收者的公鑰加密)。
32 rsa.FromXmlString(bobPublicKey);
33
34 // 欲加密的原文。
35 string orgText = "Hello, 密碼學!";
36
37 // 加密。
38 byte[] orgData = Encoding.Default.GetBytes(orgText);
39 byte[] encryptedData = rsa.Encrypt(orgData, false);
40
41 // 將加密過的文字顯示於 UI。
42 txtEncrypted.Text = Convert.ToBase64String(encryptedData);
43 }
44
45 private void btnDecrypt_Click(object sender, EventArgs e)
46 {
47 // 建立 RSA 加解密物件。
48 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
49
50 // 將私密金鑰匯入 RSA 物件。
51 rsa.FromXmlString(bobPrivateKey);
52
53 byte[] encryptedData = Convert.FromBase64String(txtEncrypted.Text);
54
55 // 解密。
56 byte[] decryptedData = rsa.Decrypt(encryptedData, false);
57 txtDecrypted.Text = Encoding.Default.GetString(decryptedData);
58 }
59 }
60 }
程式的 Form1_Load 事件處理程序(第 18~24 行)會先產生接收者的金鑰對,並將私鑰和公鑰分別保存在變數 bobPrivateKey 和 bobPublicKey 中。這裡我用 RSACryptoServiceProvider 的 ToXmlString 方法將金鑰匯出成 XML 格式的字串,此方法需要一個布林參數,當此參數為 true 時,表示要包含公鑰及私鑰,若為 false 則只傳回公鑰。因此這裡的 bobPrivateKey 其實包含了公鑰與私鑰。
加密和解密的處理過程都加了詳細的註解,應該不用再額外說明了。比較需要特別注意的是第 32 行和第 51 行,從這兩行可以看出加密跟解密時使用的是公鑰還是私鑰。此外,由於加解密的輸入與輸出資料都是 byte 陣列,因此在顯示加密的結果時,會先將資料轉成 Base64 編碼的字串(第 42 行),而在進行解密時,會先將 Base64 編碼的密文轉回 byte 陣列(第 53 行)。
使用私鑰加密,公鑰解密?
測試過公鑰加密、私鑰解密之後,也許你會想嘗試顛倒過來,用訊息發送者的私鑰加密,然後用公鑰解密。
不行,你不能這麼做。當你嘗試修改前面的範例程式碼,將加密和解密時使用的金鑰互相調換,像這樣(只列出有修改的部分):
....(略)
32 rsa.FromXmlString(bobPrivateKey);
....(略)
51 rsa.FromXmlString(bobPubliceKey);
執行時將會出現錯誤訊息:「機碼無效」(英文是 "Invalid Key")。
可是,前面不是才說過,非對稱式加密的基本規則是:「使用公鑰加密的資料只有對應的私鑰可解,而使用私鑰加密的資料只有對應的公鑰能解」?那又為什麼在撰寫程式時,使用私鑰加密會發生錯誤?
仔細想一下,使用公開金鑰加密,並利用私密金鑰解密,這種方式有其實際的應用場合,就像我們前面舉的例子;這種方式主要是用來防止資料被他人窺視。但如果反過來,假設 Alice 是用她自己的私鑰將訊息加密,那麼這段密文只有她的公鑰可解,而公鑰是可以任意散佈的,所以 Bob 也一定能用 Alice 的公鑰將密文解開。問題就在於,Alice 的公鑰任誰都可以取得,因此,不只 Bob,任何第三者只要能截取到該密文,也一定能夠將它解密。這麼一來,人人都可以輕易解密,那還要這種加密方式做什麼?
如果你花點時間思考一下上面的問題,或許會反駁:「不對!這種方式還是有用處。當我希望我發布的訊息不會遭到第三者篡改時,就可以先用我的私鑰將訊息加密,如此一來,別人如果要看訊息原文,就必須用我的公開金鑰解密,如果解密失敗,那就表示這段密文被篡改過了。」
是的,這種方式的確可以防止資料被篡改。不過,RSA 加解密演算法需要複雜的運算,並不適合用來加密大量資料;況且,如果只是要防止資料被篡改,並不需要將整份明文加密,我們需要的是能夠檢查文件是否被篡改的方法,而這個方法,就是接下來要談的數位簽章(digital signature)。
數位簽章
精確地說,數位簽章並不能防止訊息被篡改,而是讓我們能夠判斷訊息是否遭到篡改。那麼,它是如何做到的?首先,訊息傳送者使用雜湊演算法 (hashing algorithm,例如:SHA-1)將明文加以運算,得到一組雜湊值,這組雜湊值有個正式的名稱,叫做「訊息摘要」(message digest)。顧名思義,它就是將原始資料運算之後得到的一小塊摘要資料,這塊摘要資料雖然小,但是卻足以用來驗證原始資料是否遭到篡改。你也可以把訊息摘要想成是原始資料的縮影,但請注意它既非壓縮,也不是原始資料加密的結果;也就是說,你無法將訊息摘要還原成原始資料(因為雜湊函數是單向、不可逆的)。你或許會質疑,兩份不同的文件是否可能產生相同的雜湊值?儘管機率很低,但還是有可能的(因此便可能偽造簽章),如果對此議題有興趣,可以上網找一下關鍵字「加密 雜湊碰撞」,或者直接一點:「SHA-1 被破解」。
舉例來說,假設 Alice 要傳遞一段訊息給 Bob,而且她希望 Bob 收到時,能夠確認該訊息是否遭到篡改,整個處理過程描述如下:
1. Alice 使用雜湊演算法針對該訊息加以運算並產生雜湊值,然後用私鑰將雜湊值加密,以產生簽章,再將這個加密過的簽章連同訊息內容一併傳遞給 Bob。
2. 當 Bob 收到訊息和加密過的簽章,他可以將訊息透過相同的雜湊演算法重新計算雜湊值,然後用 Alice 的公鑰將簽章解密,以取得原有的雜湊值,最後再比對兩個雜湊值,若不相等, 即表示訊息被篡改了。
注意 Alice 必須用私鑰將雜湊值加密,如此一來,就算有第三者從中攔截訊息,並篡改其內容,然後利用雜湊演算法產生一組新的雜湊值,並替換掉原本的雜湊值,也無法達成其偽造訊息的目的。因為 Bob 會先用 Alice 的公鑰將簽章解密,如果簽章被替換過,就無法解密成功,當然 Bob 也就能發現訊息已經遭到篡改了。
我們可以根據前面描述的情境寫一個範例程式,來模擬及測試數位簽章。首先看一下範例程式的執行畫面:
畫面分成上下兩個區塊,上方區塊代表訊息傳送方,也就是 Alice,下方則是 Bob;紅字所標示的,是箭頭所指的控制項名稱。
當 Alice 要傳送訊息給 Bob 時,首先要產生數位簽章,而視窗中的「產生簽章」按鈕就是在做這件事情。簽章產生完畢之後,Alice 將明文、簽章、公開金鑰一併傳送給 Bob,此時再按「驗證簽章」按鈕,以執行驗證的動作。這裡我將 Alice 和 Bob 的行為分別用兩個類別封裝起來,而根據前面的描述可以知道,Alice 需要對文件簽章,並對外公布其公開金鑰,因此 Alice 類別會像這樣:
1 public class Alice
2 {
3 RSACryptoServiceProvider m_Rsa;
4
5 public Alice()
6 {
7 m_Rsa = new RSACryptoServiceProvider(); // 建立 RSA 加密器,並自動建立一組金鑰對。
8 }
9
10 public byte[] HashAnsSign(byte[] dataToSign)
11 {
12 // 使用 SHA1 演算法產生雜湊值,然後產生簽章。
13 return m_Rsa.SignData(dataToSign, new SHA1CryptoServiceProvider());
14 }
15
16 public string PublicKey
17 {
18 get
19 {
20 return m_Rsa.ToXmlString(false); // 傳入 false 代表只傳回公鑰的 XML 字串。
21 }
22 }
23 }
其中 HashAndSign 方法就是用來產生文件簽章,而 PublicKey 屬性則是 Alice 對外界公佈的公開金鑰,其內容格式為 XML 字串。計算雜湊值的演算法是 SHA-1,產生的簽章會是一塊大小為 128 bytes 的二進位資料區塊。
接著,Bob 只要作驗證簽章的動作,其類別定義如下:
1 public class Bob
2 {
3 public bool VerifySignedData(byte[] data, byte[] signature, string publicKey)
4 {
5 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
6 rsa.FromXmlString(publicKey); // 需要用到傳送者(Alice)的公鑰將簽章解密。
7 return rsa.VerifyData(data, new SHA1CryptoServiceProvider(), signature);
8 }
9 }
VerifySignedData 方法接受三個參數,data 是訊息的原始資料,signature 是簽章,publicKey 則是訊息傳送者的公開金鑰。
Alice 和 Bob 物件是在範例程式的視窗載入時就已經建立好。當「產生簽章」按鈕按下時,要執行的處理如下:
1 private void btnSign_Click(object sender, EventArgs e)
2 {
3 byte[] orgData = Encoding.Default.GetBytes(txtOrgData.Text); // 將訊息內容轉成 byte 陣列。
4 byte[] signature = alice.HashAnsSign(orgData); // Alice 產生數位簽章。
5
6 txtSignature.Text = Convert.ToBase64String(signature); // 將數位簽章的內容轉成 Base64 字串,以便顯示。
7 lblSignedLength.Text = "簽章大小: " + signature.Length.ToString() + " bytes";
8 }
最後是「驗證簽章」按鈕的事件處理程序:
1 private void btnVerifySignedData_Click(object sender, EventArgs e)
2 {
3 byte[] orgData = Encoding.Default.GetBytes(txtOrgData.Text); // 訊息原文
4 byte[] signedData = Convert.FromBase64String(txtSignature.Text); // 簽章資料
5
6 bool ok = bob.VerifySignedData(orgData, signedData, alice.PublicKey);
7 if (ok)
8 {
9 MessageBox.Show("驗證成功!");
10 }
11 else
12 {
13 MessageBox.Show("簽章無效!");
14 }
15 }
以下為執行結果:
如果您也有興趣練習看看,可以下載本文的附件,裡面包含數位簽章範例的完整原始碼。MSDN 網站上也有範例可以參考:http://msdn2.microsoft.com/zh-tw/library/9tsc5d0z(VS.80).aspx,而且你會發現 MSDN 上面的範例跟這裡的有些不同,特別是匯入跟匯出金鑰的部份,我用的是 RSACryptoServiceProvider 的 ToXmlString 和 FromXmlString 方法,它是用 ExportParameters 和 ImportParameters 方法。
另外要說明的是,這裡的數位簽章範例程式只是簡單地示範數位簽章的實作,因此該範例並沒有將訊息加密。實際應用時,如果你希望傳遞的訊息不僅可以防止篡改,而且要避免第三者窺視,也可以再加上前面介紹的公鑰加密、私鑰解密的方法,將訊息用接收者的公鑰加密。如此一來,傳送者和接收者的公鑰及私鑰便都會派上用場,其運作流程如下(Alice 為訊息傳送者,Bob 為接收者):
1. Alice 使用雜湊演算法產生訊息摘要。
2. Alice 用私鑰將訊息摘要加密,以產生數位簽章。
3. Alice 用 Bob 的公鑰將訊息加密。
4. Alice 將加密過的訊息連同簽章一併傳送給 Bob。
5. Bob 用 Alice 的公鑰將簽章解密還原成訊息摘要。
6. Bob 用自己的私鑰將密文解密。
7. Bob 將解密後的資料以雜湊演算法重新計算訊息摘要。
8. Bob 比對步驟 5 跟步驟 7 產生的訊息摘要是否相同,以驗證資料是否遭到篡改。
配著圖看會比較清楚:
小結
這篇文章只是個起點,當你開始動手練習,並參考網路上多種範例之後,就會發現密碼學這塊領域在實作上的細節還挺多的。比如說,你可能會發現這裡的範例程式,每次執行時都會重新產生一對金鑰,可是如果你希望金鑰對只產生一次,存放在你的硬碟裡,以後每次執行時就直接取用先前建立的金鑰對,這個問題該如何處理?(你得先了解什麼是「金鑰容器」)或者,你可能會想了解如何實作對稱式加解密,那麼你可以試試 AES(RijndaelManaged 類別)。總之,這塊領域還有很多東西等著我們探索與學習。
2009年7月21日 星期二
2009年7月16日 星期四
關於農曆日期的取得問題
自己可以取得日的天干地支計算,計算方式是以1900/1/1為基底起算日期,取得該日的天干地支序,然後對應取得與欲取得日期所差天數,除以60,但是若要取得月份和年度因為牽涉到各月份日期天數不一,而且可能有潤年和潤月的問題,需取得日期格式如:2005/11/2中式日期為:乙酉年丁亥月庚寅日....
1. 請在此區域輸入程式碼
2. {
3. 主要函数:农历转换成公历
4. 公历转换成农历
5. 计算潮汐时间
6. 求某日有哪些节日,节气
7. 求某日干支
8. 本单元的数据及函数基本上都来自 http://www.21softs.com/ 所提供
9. 的万年历Javaforbidden代码。
10. 潮汐算法主要参考自: <http://www.yuqu.com/haidiao/hai019.htm>
11. 第一次高潮 F1= 0.8 X ((day mod 15) - 1) + 高潮间隙
12. 低潮 F2= F1 + 6:12
13. 第二次高潮 F3= F2 + 12:24 - 6:12
14. Javaforbidden的原作者是台湾的 Sean Lin (林洵賢) <sean@4u.net>
15. 简体中文(作者授权) Sumyou (梅竹松) <bushi@21softs.com>
16. 有关于原代码详细情况,请访问 http://www.21softs.com/
17. 本单元由Mostone.Jiang 业余兴趣所改写
18. 源代码无条件共享,有Bug或是改进,
19. 烦请mail me.
20. Mostone.Jiang 漠石 <mostone@hotmail.com>
21. 2003.04
22. }
23. unit CnBase;
24. interface
25. uses SysUtils, DateUtils, Controls;
26. type
27. THzDate = record //农历日期
28. Year: integer;
29. Month: integer;
30. Day: integer;
31. isLeap: Boolean;
32. end;
33. TGzDate = record //干支日期
34. Year: integer;
35. Month: integer;
36. Day: integer;
37. // FullDate: string; //如:癸未年丙辰月丁巳日
38. end;
39. TCnDate = record //包含数字及干支显示的日期
40. Date: TDate;
41. HzDate: THzDate;
42. GzDate: TGzDate;
43. end;
44. const
45. lunarInfo: array[0..200] of WORD =(
46. $4bd8,$4ae0,$a570,$54d5,$d260,$d950,$5554,$56af,$9ad0,$55d2,
47. $4ae0,$a5b6,$a4d0,$d250,$d295,$b54f,$d6a0,$ada2,$95b0,$4977,
48. $497f,$a4b0,$b4b5,$6a50,$6d40,$ab54,$2b6f,$9570,$52f2,$4970,
49. $6566,$d4a0,$ea50,$6a95,$5adf,$2b60,$86e3,$92ef,$c8d7,$c95f,
50. $d4a0,$d8a6,$b55f,$56a0,$a5b4,$25df,$92d0,$d2b2,$a950,$b557,
51. $6ca0,$b550,$5355,$4daf,$a5b0,$4573,$52bf,$a9a8,$e950,$6aa0,
52. $aea6,$ab50,$4b60,$aae4,$a570,$5260,$f263,$d950,$5b57,$56a0,
53. $96d0,$4dd5,$4ad0,$a4d0,$d4d4,$d250,$d558,$b540,$b6a0,$95a6,
54. $95bf,$49b0,$a974,$a4b0,$b27a,$6a50,$6d40,$af46,$ab60,$9570,
55. $4af5,$4970,$64b0,$74a3,$ea50,$6b58,$5ac0,$ab60,$96d5,$92e0,
56. $c960,$d954,$d4a0,$da50,$7552,$56a0,$abb7,$25d0,$92d0,$cab5,
57. $a950,$b4a0,$baa4,$ad50,$55d9,$4ba0,$a5b0,$5176,$52bf,$a930,
58. $7954,$6aa0,$ad50,$5b52,$4b60,$a6e6,$a4e0,$d260,$ea65,$d530,
59. $5aa0,$76a3,$96d0,$4afb,$4ad0,$a4d0,$d0b6,$d25f,$d520,$dd45,
60. $b5a0,$56d0,$55b2,$49b0,$a577,$a4b0,$aa50,$b255,$6d2f,$ada0,
61. $4b63,$937f,$49f8,$4970,$64b0,$68a6,$ea5f,$6b20,$a6c4,$aaef,
62. $92e0,$d2e3,$c960,$d557,$d4a0,$da50,$5d55,$56a0,$a6d0,$55d4,
63. $52d0,$a9b8,$a950,$b4a0,$b6a6,$ad50,$55a0,$aba4,$a5b0,$52b0,
64. $b273,$6930,$7337,$6aa0,$ad50,$4b55,$4b6f,$a570,$54e4,$d260,
65. $e968,$d520,$daa0,$6aa6,$56df,$4ae0,$a9d4,$a4d0,$d150,$f252,
66. $d520);
67. solarMonth: array[0..11] of integer = (31,28,31,30,31,30,31,31,30,31,30,31);
68. Gan: array[0..9] of string[2] =
69. ('甲','乙','丙','丁','戊'
70. ,'己','庚','辛','壬','癸');
71. Zhi: array[0..11] of string[2] =
72. ('子','丑','寅','卯','辰','巳',
73. '午','未','申','酉','戌','亥');
74. Animals: Array[0..11] of string[2] =
75. ('鼠','牛','虎','兔','龙','蛇'
76. ,'马','羊','猴','鸡','狗','猪');
77. solarTerm: Array[0..23] of string[4] =
78. ('小寒','大寒','立春','雨水'
79. ,'惊蛰','春分','清明','谷雨'
80. ,'立夏','小满','芒种','夏至'
81. ,'小暑','大暑','立秋','处暑'
82. ,'白露','秋分','寒露','霜降'
83. ,'立冬','小雪','大雪','冬至');
84. sTermInfo: Array[0..23] of integer =
85. (0,21208,42467,63836
86. ,85337,107014,128867,150921
87. ,173149,195551,218072,240693
88. ,263343,285989,308563,331033
89. ,353350,375494,397447,419210
90. ,440795,462224,483532,504758);
91. nStr1: array[0..10] of string[2] =
92. ('日','一','二','三','四','五'
93. ,'六','七','八','九','十');
94. nStr2: Array[0..4] of string[2] = ('初','十','廿','卅','□');
95. monthName: Array[0..11] of string[3] =
96. ('JAN','FEB','MAR','APR','MAY','JUN'
97. ,'JUL','AUG','SEP','OCT','NOV','DEC');
98. //公历节日 *表示放假日
99. sFtv: Array[0..95] of string =(
100. '0101*新年元旦',
101. '0202 世界湿地日',
102. '0207 国际声援南非日',
103. '0210 国际气象节',
104. '0212 国际足球比赛日',
105. '0214 西方情人节',
106. '0301 国际海豹日',
107. '0303 全国爱耳日',
108. '0308 国际妇女节',
109. '0312 植树节 孙中山逝世纪念日',
110. '0314 国际警察日',
111. '0315 国际消费者权益日',
112. '0317 中国国医节 国际航海日',
113. '0321 世界森林日 消除种族歧视国际日',
114. '0321 世界儿歌日',
115. '0322 世界水日',
116. '0323 世界气象日',
117. '0324 世界防治结核病日',
118. '0325 全国中小学生安全教育日',
119. '0330 巴勒斯坦国土日',
120. '0401 愚人节 全国爱国卫生运动月(四月) 税收宣传月(四月)',
121. '0407 世界卫生日',
122. '0422 世界地球日',
123. '0423 世界图书和版权日',
124. '0424 亚非新闻工作者日',
125. '0501*国际劳动节',
126. '0504 中国五四青年节',
127. '0505 碘缺乏病防治日',
128. '0508 世界红十字日',
129. '0512 国际护士节',
130. '0515 国际家庭日',
131. '0517 世界电信日',
132. '0518 国际博物馆日',
133. '0520 全国学生营养日',
134. '0523 国际牛奶日',
135. '0531 世界无烟日',
136. '0601*国际儿童节',
137. '0605 世界环境日',
138. '0606 全国爱眼日',
139. '0617 防治荒漠化和干旱日',
140. '0623 国际奥林匹克日',
141. '0625 全国土地日',
142. '0626 国际反毒品日',
143. '0701 中国共产党建党日 世界建筑日',
144. '0702 国际体育记者日 精品推介站(http://www.21softs.com/)正式对外开放纪念日',
145. '0707 中国人民抗日战争纪念日',
146. '0711 世界人口日',
147. '0730 非洲妇女日',
148. '0801 中国建军节',
149. '0808 中国男子节(爸爸节)',
150. '0815 日本正式宣布无条件投降日',
151. '0908 国际扫盲日 国际新闻工作者日',
152. '0910*教师节',
153. '0914 世界清洁地球日',
154. '0916 国际臭氧层保护日',
155. '0918 九·一八事变纪念日',
156. '0920 国际爱牙日',
157. '0927 世界旅游日',
158. '1001*国庆节 世界音乐日 国际老人节',
159. '1001 国际音乐日',
160. '1002 国际和平与民主自由斗争日',
161. '1004 世界动物日',
162. '1008 全国高血压日',
163. '1008 世界视觉日',
164. '1009 世界邮政日 万国邮联日',
165. '1010 辛亥革命纪念日 世界精神卫生日',
166. '1013 世界保健日 国际教师节',
167. '1014 世界标准日',
168. '1015 国际盲人节(白手杖节)',
169. '1016 世界粮食日',
170. '1017 世界消除贫困日',
171. '1022 世界传统医药日',
172. '1024 联合国日 世界发展信息日',
173. '1031 世界勤俭日',
174. '1107 十月社会主义革命纪念日',
175. '1108 中国记者日',
176. '1109 全国消防安全宣传教育日',
177. '1110 世界青年节',
178. '1111 国际科学与和平周(本日所属的一周)',
179. '1112 孙中山诞辰纪念日',
180. '1114 世界糖尿病日',
181. '1117 国际大学生节 世界学生节',
182. '1121 世界问候日 世界电视日',
183. '1129 国际声援巴勒斯坦人民国际日',
184. '1201 世界艾滋病日',
185. '1203 世界残疾人日',
186. '1205 国际经济和社会发展志愿人员日',
187. '1208 国际儿童电视日',
188. '1209 世界足球日',
189. '1210 世界人权日',
190. '1212 西安事变纪念日',
191. '1213 南京大屠杀(1937年)纪念日!紧记血泪史!',
192. '1221 国际篮球日',
193. '1224 平安夜',
194. '1225*圣诞节',
195. '1229 国际生物多样性日');
196. //某月的第几个星期几。 5,6,7,8 表示到数第 1,2,3,4 个星期几
197. wFtv: Array[0..11] of string = (
198. '0110 黑人日',
199. '0150 世界麻风日', //一月的最后一个星期日(月倒数第一个星期日)
200. '0520 国际母亲节',
201. '0530 全国助残日',
202. '0630 父亲节',
203. '0911 劳动节',
204. '0932 国际和平日',
205. '0940 国际聋人节 世界儿童日',
206. '0950 世界海事日',
207. '1011 国际住房日',
208. '1013 国际减轻自然灾害日(减灾日)',
209. '1144 感恩节');
210. //农历节日
211. lFtv: Array[0..10] of string = (
212. '0101*春节',
213. '0115*元宵节 中国情人节',
214. '0202 龙抬头节',
215. '0323 妈祖生辰 (天上圣母诞辰)',
216. '0505*端午节',
217. '0707 七七中国情人节',
218. '0815*中秋节',
219. '0909*重阳节',
220. '1208 腊八节',
221. '1223 灶君(祭灶)节',
222. '0100*除夕');
223. function lYearDays(y: integer): integer; //返回农历 y年的总天数
224. function leapDays(y: integer): integer; //返回农历 y年闰月的天数
225. function leapMonth(y: integer): integer; //返回农历 y年闰哪个月 1-12 , 没闰返回 0
226. function monthDays(y, m: integer): integer; //返回农历 y年m月的总天数
227. function Lunar(objDate: TDate): THzDate; //算出农历, 传入日期控件, 返回农历日期控件
228. function solarDays(y, m: integer): integer; //返回公历 y年m月的天数
229. function cyclical(num: integer): string; //传入 offset 返回干支, 0=甲子
230. function HzLunar(objDate: THzDate): TDate; //算出公历, 传入农历日期控件, 返回公历
231. function ChkHzDate(objDate: THzDate): Boolean; //检查农历日期是否合法
232. function sTerm(y, n: integer): TDateTime; //某年的第n个节气为几日(从0小寒起算)
233. function GetGZ(y, m: integer; objDate: TDate): TGzDate; //求年柱,月柱,日柱(年,月为农历数字,objDate为当天的公历日期)
234. function GetCnDay(objDate: THzDate): string;
235. function GetCnMonth(ObjDate: THzDate): string;
236. function GetCnYear(objDate: THzDate): string;
237. function GetCnWeek(day: TDate): string;
238. //取得潮汐时间 jth: 潮汐间隙小时,jtm: 潮汐间隙分钟
239. function GetZX(HzDay: Integer; zxjx: TTime= 0.42709491898): string;
240. // 指定月分第几个星期几是第几天
241. function Getd0(y, m: Integer; S: string): Integer;
242. // 去除节日列表中的标记,返回以,相隔的字符串
243. procedure ClearJR(S: string; var strSave: string);
244. //取得指定日期的节日
245. function GetDayOfJR(day: TCnDate):string;
246. // 取得指定日期的节气
247. function GetDayOfJQ(day: TDate): string;
248. implementation
249. {*****************************************************************************
250. 日期计算
251. *****************************************************************************}
252. //====================================== 返回农历 y年的总天数
253. function lYearDays(y: integer): integer;
254. var
255. i, sum: integer;
256. begin
257. sum:= 348;
258. i:= $8000;
259. while i > $8 do
260. begin
261. if (lunarInfo[y - 1900] and i) > 0 then Inc(sum);
262. i:= i shr 1;
263. end;
264. Result:= sum + leapDays(y);
265. end;
266. //====================================== 返回农历 y年闰月的天数
267. function leapDays(y: integer): integer;
268. begin
269. if Boolean(leapMonth(y)) then
270. begin
271. if (lunarInfo[y - 1899] and $f) = $f then Result := 30 else Result := 29;
272. end
273. else Result := 0;
274. end;
275. //====================================== 返回农历 y年闰哪个月 1-12 , 没闰返回 0
276. function leapMonth(y: integer): integer;
277. var
278. lm: Word;
279. begin
280. lm:= lunarInfo[y - 1900] and $f;
281. if lm = $f then Result:= 0 else Result:= lm;
282. end;
283. //====================================== 返回农历 y年m月的总天数
284. function monthDays(y, m: integer): integer;
285. var
286. temp1, temp2, temp3: Word;
287. begin
288. temp1:= lunarInfo[y - 1900];
289. temp2:= $8000;
290. if m > 1 then temp2:= $8000 shr (m - 1);
291. // temp2:= $10000 shr (m - 1);
292. temp3:= temp1 and temp2;
293. // if Boolean(temp3) then
294. // if Boolean(lunarInfo[y - 1900] and ($8000 shr (m - 1))) then
295. if temp3 > 0 then
296. Result:= 30
297. else Result:= 29;
298. end;
299. //====================================== 算出农历, 传入日期控件, 返回农历日期控件
300. function Lunar(objDate: TDate): THzDate;
301. var
302. i, leap, temp, offset: integer;
303. begin
304. temp:= yearof(objDate);
305. if (temp < 1901) or (temp > 2100) then exit;
306. offset:= DaysBetween(EncodeDate(1900,1,31),objDate);
307. i:= 1900;
308. while (i < 2100) and (offset > 0) do
309. begin
310. temp:= lYearDays(i);
311. offset:= offset - temp;
312. Inc(i);
313. end;
314. if (offset < 0) then
315. begin
316. offset:= offset + temp;
317. i:= i - 1;
318. end;
319. Result.Year:= i;
320. leap:= leapMonth(i); //闰哪个月
321. Result.isLeap:= False;
322. i:=1;
323. while (i < 13) and (offset > 0) do
324. begin
325. if (leap > 0) and (i = leap + 1) and (Result.isLeap = False) then
326. begin
327. i:= i - 1;
328. Result.isLeap:= True;
329. temp:= leapDays(Result.Year);
330. end else temp:= monthDays(Result.Year, i);
331. if (Result.isLeap = True) and (i = leap + 1) then
332. Result.isLeap:= False;
333. offset:= offset - temp;
334. inc(i);
335. end;
336. if (offset = 0) and (leap > 0) and (i = leap + 1) then
337. begin
338. if Result.isLeap then Result.isLeap:= False
339. else begin
340. Result.isLeap:= True;
341. i:= i - 1;
342. end;
343. end;
344. if offset < 0 then
345. begin
346. offset:= offset + temp;
347. i:= i - 1;
348. end;
349. Result.Month:= i;
350. Result.Day:= offset + 1;
351.
352. end;
353. //=============================== // 求年柱,月柱,日柱
354. //============= 年,月为农历数字,objDate为当天的公历日期
355. function GetGZ(y, m: integer; objDate: TDate): TGzDate;
356. var
357. term: TDate;
358. sy, sm, sd: Word;
359. begin
360. DecodeDate(objDate, sy, sm, sd);
361. term:= sTerm(sy, (sm - 1) * 2); // 当月的节气日期
362. //年柱 1900年立春后为庚子年(60进制36)
363. Result.Year:= sy - 1900 + 36;
364. //依立春日期调整年柱
365. if (sm = 2) and (objDate < term) then
366. Result.Year:= sy - 1900 + 35;
367. //月柱 农历1900年1月小寒以前为 丙子月(60进制12)
368. Result.Month:= (sy - 1900) * 12 + sm + 11;
369. //依节气调整月柱
370. if objDate >= DateOf(term) then Result.Month:= (sy - 1900) * 12 + sm + 12;
371. // 1900/1/1 日柱为甲辰日(60进制10)
372. Result.Day:= DaysBetween(EncodeDate(1900,1,1),objDate) + 10;
373. end;
374. //====================================== 算出公历, 传入农历日期控件, 返回公历
375. function HzLunar(objDate: THzDate): TDate;
376. var
377. i, j, t, leap, temp, offset: integer;
378. isLeap: Boolean;
379. y, m: integer;
380. begin
381. Result:= EncodeDate(1,1,1);
382. if not ChkHzDate(objDate) then exit;
383. isLeap:= False;
384. y:= objDate.Year;
385. m:= objDate.Month;
386. leap:= leapMonth(y);
387. //本年内从大年初一过来的天数
388. offset:= 0;
389. i:= 1;
390. while i < m do
391. begin
392. if i = leap then
393. begin
394. if isLeap then
395. begin
396. temp:= leapDays(y);
397. isLeap:= False;
398. end else
399. begin
400. temp:= monthDays(y, i);
401. isLeap:= True;
402. i:= i - 1;
403. end;
404. end else
405. temp:= monthDays(y, i);
406. offset:= offset + temp;
407. Inc(i);
408. end;
409. offset:= offset + objDate.Day - 1;
410. if (m = leap) and objDate.isLeap then //若为闰月,再加上前一个非闰月天数
411. offset:= offset + monthDays(y, m);
412. // 该年到 2000.1.1 这几年的天数
413. if y > 2000 then
414. begin
415. i:= 2000;
416. j:= y - 1;
417. end else
418. begin
419. i:= y;
420. j:= 1999;
421. end;
422. temp:= 0;
423. for t:= i to j do
424. begin
425. temp:= temp + lYearDays(t);
426. end;
427. if y > 1999 then offset:= offset + temp
428. else offset:= offset - temp;
429. //农历二零零零年大年初一的阳历为 2000.2.5
430. Result:= incDay(EncodeDate(2000,2,5),offset);
431. end;
432. //====================================== 检查农历日期是否合法
433. function ChkHzDate(objDate: THzDate): Boolean;
434. begin
435. if (objDate.Year > 2099) or (objDate.Year < 1901)
436. or (objDate.Month > 12) or (objDate.Day > 31) then
437. begin
438. Result:= False;
439. exit;
440. end;
441. Result:= True;
442. if objDate.isLeap then
443. begin
444. if leapMonth(objDate.Year) = objDate.Month then
445. begin
446. if leapDays(objDate.Year) < objDate.Day then
447. Result:= False;
448. end else Result:= False;
449. end else
450. begin
451. if monthDays(objDate.Year,objDate.Month) < objDate.Day then
452. Result:= False;
453. end;
454. end;
455. //===== 某年的第n个节气为几日(从0小寒起算)
456. function sTerm(y, n: integer): TDateTime;
457. var
458. temp: TDateTime;
459. t,tt: real;
460. i: Int64;
461. begin
462. t:= sTermInfo[n];
463. t:= t * 60000;
464. tt:= 31556925974.7 * (y - 1900);
465. t:= t + tt;
466. i:= Round(t);
467. Temp:= IncMilliSecond(EncodeDateTime(1900,1,6,2,5,0,0),i);
468. Result:= temp;
469. { var offDate = new Date( ( 31556925974.7*(y-1900) + sTermInfo[n]*60000 ) + Date.UTC(1900,0,6,2,5) );
470. return(offDate.getUTCDate());
471. }
472. end;
473.
474. //==============================返回公历 y年m月的天数
475. function solarDays(y, m: integer): integer;
476. begin
477. if m = 2 then
478. begin
479. if ((y mod 4) = 0) and ((y mod 100) <> 0) or ((y mod 400) = 0) then
480. Result:= 29
481. else Result:= 28;
482. end else Result:= solarMonth[m - 1];
483. end;
484. //============================== 传入 offset 返回干支, 0=甲子
485. function cyclical(num: integer): string;
486. begin
487. Result:= Gan[num mod 10] + Zhi[num mod 12];
488. end;
489. //
490. function GetCnDay(objDate: THzDate): string;
491. var
492. day: integer;
493. begin
494. day:= objDate.Day;
495. case day of
496. 1..10: Result:= nStr2[0] + nStr1[day];
497. 11..19: Result:= nStr2[1] + nStr1[day - 10];
498. 20: Result:= nStr1[2] + nStr1[10];
499. 21..29: Result:= nStr2[2] + nStr1[day - 20];
500. 30: Result:= nStr1[3] + nStr1[10];
501. end;
502. end;
503. function GetCnMonth(ObjDate: THzDate): string;
504. var
505. month: integer;
506. begin
507. month:= objDate.Month;
508. case month of
509. 1..10: Result:= nStr1[month];
510. 11..12: Result:= nStr1[10] + nStr1[month - 10];
511. end;
512. if objDate.isLeap then Result:= '闰' + Result;
513. Result:= Result + '月';
514. end;
515. function GetCnYear(objDate: THzDate): string;
516. var
517. year, temp: integer;
518. zero: string;
519. begin
520. year:= objDate.Year;
521. zero:= '零';
522. temp:= year div 1000;
523. Result:= nStr1[temp];
524. year:= year - temp * 1000;
525. if year >= 100 then
526. begin
527. temp:= year div 100;
528. Result:= Result + nStr1[temp];
529. year:= year - temp * 100;
530. end
531. else
532. Result:= Result + zero;
533. if year >= 10 then
534. begin
535. temp:= year div 10;
536. Result:= Result + nStr1[temp];
537. year:= year - temp * 10;
538. end
539. else
540. Result:= Result + zero;
541. if year = 0 then Result:= Result + zero else
542. Result:= Result + nStr1[year];
543. Result:= Result + '年';
544. end;
545. // 潮汐算法主要参考自: <http://www.yuqu.com/haidiao/hai019.htm>
546. //
547. // 第一次高潮 F1= 0.8 X ((day mod 15) - 1) + 高潮间隙
548. // 低潮 F2= F1 + 6:12
549. // 第二次高潮 F3= F2 + 12:24 - 6:12
550. function GetZX(HzDay: Integer; zxjx: TTime= 0.42709491898): string;
551. var
552. Pos: Integer;
553. temp: Double;
554. h, m: Word;
555. begin
556. if zxjx = 0 then zxjx:= 0.42709491898;
557. Pos:= HzDay mod 15;
558. if Pos = 0 then Pos:= 15;
559. Inc(Pos, -1);
560. temp:= 0.8 * Pos;
561. h:= Trunc(temp);
562. m:= Trunc((temp - h) * 10);
563. m:= 60 * h + m * 6;
564. zxjx:= IncMinute(zxjx, m);
565. Result:= FormatDateTime(' hh:mm',zxjx); //高潮,低潮间隔是二个#32空格
566. zxjx:= IncMinute(zxjx, 372);
567. Result:= Result + FormatDateTime(' hh:mm',zxjx);
568. zxjx:= IncMinute(zxjx, 372);
569. Result:= Result + FormatDateTime(' hh:mm',zxjx);
570. end;
571. // 指定月分第几个星期几是第几天
572. function Getd0(y, m: Integer; S: string): Integer;
573. var
574. cntDay, cntWeek, idxPos, idxWeek: integer;
575. CurDay: TDate;
576. i: integer;
577. begin
578. cntDay:= solarDays(y, m);
579. idxPos:= strtoint(Copy(S,1,1));
580. idxWeek:= strtoint(Copy(S,2,1));
581. cntWeek:= 1;
582. if idxPos< 5 then
583. begin
584. CurDay:= EncodeDate(y, m, 1);
585. for i:= 1 to cntDay do
586. begin
587. if (DayOfWeek(CurDay) - 1) = idxWeek then
588. if cntWeek = idxPos then break else Inc(cntWeek);
589. CurDay:= IncDay(CurDay);
590. end;
591. Result:= i;
592. end
593. else begin
594. idxPos:= idxPos - 4;
595. CurDay:= EncodeDate(y, m, cntDay);
596. for i:= cntDay downto 1 do
597. begin
598. if (DayOfWeek(CurDay) - 1) = idxWeek then
599. if cntWeek = idxPos then break else Inc(cntWeek);
600. CurDay:= IncDay(CurDay, -1);
601. end;
602. Result:= i;
603. end;
604. end;
605. // 去除节日列表中的标记,返回以,相隔的字符串
606. procedure ClearJR(S: string; var strSave: string);
607. var
608. PosOfSpc: Integer;
609. ss: string;
610. begin
611. s:= Trim(s);
612. repeat
613. PosOfSpc:= Pos(' ', S);
614. if PosOfSpc > 0 then ss:= Copy(s, 1, PosOfSpc -1)
615. else ss:= s;
616. ss:= TrimLeft(ss);
617. if Copy(ss,1,1) = '*' then Delete(ss,1,1);
618. if strSave = '' then strSave:= ss
619. else strSave:= strSave + ',' + ss;
620. Delete(s, 1, PosOfSpc);
621. until PosOfSpc = 0;
622. end;
623. // 取得指定日期的节气
624. function GetDayOfJQ(day: TDate): string;
625. var
626. jq: Integer;
627. term: TDateTime;
628. begin
629. Result:= '';
630. jq:= (MonthOf(day) - 1) * 2;
631. term:= sTerm(Yearof(day), jq); //节气时间
632. if DateOf(term) = day then Result:= solarTerm[jq]
633. else
634. begin
635. term:= sTerm(Yearof(day), jq + 1); //中气时间
636. if DateOf(term) = day then Result:= solarTerm[jq+1];
637. end;
638. if Result<>'' then
639. Result:= Result + ' (时间:' + FormatDateTime('hh:mm',term) + ')';
640. end;
641.
642. //取得指定日期的节日
643. function GetDayOfJR(day: TCnDate):string;
644. var
645. H: THzDate;
646. i: Integer;
647. y, m, d: Word;
648. m0, d0: Integer;
649. lm: Boolean;
650. s, strSave: string;
651. begin
652. strSave:= '';
653. //农历节日
654. H:= day.HzDate;
655. m:= H.Month;
656. lm:= H.isLeap;
657. d:= H.Day;
658. if not lm then
659. for i:= Low(lFtv) to High(lFtv) do
660. begin
661. m0:= strtoint(Copy(lFtv[i], 1, 2));
662. d0:= strtoint(Copy(lFtv[i],3,2));
663. if (m0 = m) and (d0 = d) then
664. begin
665. s:= lFtv[i];
666. Delete(s,1,4);
667. ClearJR(s,strSave);
668. end;
669. end;
670. //公历节日
671. DecodeDate(day.Date, y, m, d);
672. for i:= Low(sFtv) to High(sFtv) do
673. begin
674. m0:= strtoint(sFtv[i][1] + sFtv[i][2]);
675. d0:= strtoint(sFtv[i][3] + sFtv[i][4]);
676. if (m0 = m) and (d0 = d) then
677. begin
678. S:= sFtv[i];
679. Delete(S,1,4);
680. ClearJr(s,strSave);
681. end;
682. end;
683. for i:= Low(wFtv) to High(wFtv) do
684. begin
685. m0:= strtoint(Copy(wFtv[i],1,2));
686. if m0 = m then
687. begin
688. d0:= Getd0(y, m, Copy(wFtv[i],3,2));
689. if (d0 = d) then
690. begin
691. S:= wFtv[i];
692. Delete(S, 1, 4);
693. ClearJR(s,strSave);
694. end;
695. end;
696. end;
697. Result:= strSave;
698. end;
699. function GetCnWeek(day: TDate): string;
700. begin
701. Result:= '星期' + nStr1[DayOfWeek(day) - 1]
702. end;
703. end.
1. 請在此區域輸入程式碼
2. {
3. 主要函数:农历转换成公历
4. 公历转换成农历
5. 计算潮汐时间
6. 求某日有哪些节日,节气
7. 求某日干支
8. 本单元的数据及函数基本上都来自 http://www.21softs.com/ 所提供
9. 的万年历Javaforbidden代码。
10. 潮汐算法主要参考自: <http://www.yuqu.com/haidiao/hai019.htm>
11. 第一次高潮 F1= 0.8 X ((day mod 15) - 1) + 高潮间隙
12. 低潮 F2= F1 + 6:12
13. 第二次高潮 F3= F2 + 12:24 - 6:12
14. Javaforbidden的原作者是台湾的 Sean Lin (林洵賢) <sean@4u.net>
15. 简体中文(作者授权) Sumyou (梅竹松) <bushi@21softs.com>
16. 有关于原代码详细情况,请访问 http://www.21softs.com/
17. 本单元由Mostone.Jiang 业余兴趣所改写
18. 源代码无条件共享,有Bug或是改进,
19. 烦请mail me.
20. Mostone.Jiang 漠石 <mostone@hotmail.com>
21. 2003.04
22. }
23. unit CnBase;
24. interface
25. uses SysUtils, DateUtils, Controls;
26. type
27. THzDate = record //农历日期
28. Year: integer;
29. Month: integer;
30. Day: integer;
31. isLeap: Boolean;
32. end;
33. TGzDate = record //干支日期
34. Year: integer;
35. Month: integer;
36. Day: integer;
37. // FullDate: string; //如:癸未年丙辰月丁巳日
38. end;
39. TCnDate = record //包含数字及干支显示的日期
40. Date: TDate;
41. HzDate: THzDate;
42. GzDate: TGzDate;
43. end;
44. const
45. lunarInfo: array[0..200] of WORD =(
46. $4bd8,$4ae0,$a570,$54d5,$d260,$d950,$5554,$56af,$9ad0,$55d2,
47. $4ae0,$a5b6,$a4d0,$d250,$d295,$b54f,$d6a0,$ada2,$95b0,$4977,
48. $497f,$a4b0,$b4b5,$6a50,$6d40,$ab54,$2b6f,$9570,$52f2,$4970,
49. $6566,$d4a0,$ea50,$6a95,$5adf,$2b60,$86e3,$92ef,$c8d7,$c95f,
50. $d4a0,$d8a6,$b55f,$56a0,$a5b4,$25df,$92d0,$d2b2,$a950,$b557,
51. $6ca0,$b550,$5355,$4daf,$a5b0,$4573,$52bf,$a9a8,$e950,$6aa0,
52. $aea6,$ab50,$4b60,$aae4,$a570,$5260,$f263,$d950,$5b57,$56a0,
53. $96d0,$4dd5,$4ad0,$a4d0,$d4d4,$d250,$d558,$b540,$b6a0,$95a6,
54. $95bf,$49b0,$a974,$a4b0,$b27a,$6a50,$6d40,$af46,$ab60,$9570,
55. $4af5,$4970,$64b0,$74a3,$ea50,$6b58,$5ac0,$ab60,$96d5,$92e0,
56. $c960,$d954,$d4a0,$da50,$7552,$56a0,$abb7,$25d0,$92d0,$cab5,
57. $a950,$b4a0,$baa4,$ad50,$55d9,$4ba0,$a5b0,$5176,$52bf,$a930,
58. $7954,$6aa0,$ad50,$5b52,$4b60,$a6e6,$a4e0,$d260,$ea65,$d530,
59. $5aa0,$76a3,$96d0,$4afb,$4ad0,$a4d0,$d0b6,$d25f,$d520,$dd45,
60. $b5a0,$56d0,$55b2,$49b0,$a577,$a4b0,$aa50,$b255,$6d2f,$ada0,
61. $4b63,$937f,$49f8,$4970,$64b0,$68a6,$ea5f,$6b20,$a6c4,$aaef,
62. $92e0,$d2e3,$c960,$d557,$d4a0,$da50,$5d55,$56a0,$a6d0,$55d4,
63. $52d0,$a9b8,$a950,$b4a0,$b6a6,$ad50,$55a0,$aba4,$a5b0,$52b0,
64. $b273,$6930,$7337,$6aa0,$ad50,$4b55,$4b6f,$a570,$54e4,$d260,
65. $e968,$d520,$daa0,$6aa6,$56df,$4ae0,$a9d4,$a4d0,$d150,$f252,
66. $d520);
67. solarMonth: array[0..11] of integer = (31,28,31,30,31,30,31,31,30,31,30,31);
68. Gan: array[0..9] of string[2] =
69. ('甲','乙','丙','丁','戊'
70. ,'己','庚','辛','壬','癸');
71. Zhi: array[0..11] of string[2] =
72. ('子','丑','寅','卯','辰','巳',
73. '午','未','申','酉','戌','亥');
74. Animals: Array[0..11] of string[2] =
75. ('鼠','牛','虎','兔','龙','蛇'
76. ,'马','羊','猴','鸡','狗','猪');
77. solarTerm: Array[0..23] of string[4] =
78. ('小寒','大寒','立春','雨水'
79. ,'惊蛰','春分','清明','谷雨'
80. ,'立夏','小满','芒种','夏至'
81. ,'小暑','大暑','立秋','处暑'
82. ,'白露','秋分','寒露','霜降'
83. ,'立冬','小雪','大雪','冬至');
84. sTermInfo: Array[0..23] of integer =
85. (0,21208,42467,63836
86. ,85337,107014,128867,150921
87. ,173149,195551,218072,240693
88. ,263343,285989,308563,331033
89. ,353350,375494,397447,419210
90. ,440795,462224,483532,504758);
91. nStr1: array[0..10] of string[2] =
92. ('日','一','二','三','四','五'
93. ,'六','七','八','九','十');
94. nStr2: Array[0..4] of string[2] = ('初','十','廿','卅','□');
95. monthName: Array[0..11] of string[3] =
96. ('JAN','FEB','MAR','APR','MAY','JUN'
97. ,'JUL','AUG','SEP','OCT','NOV','DEC');
98. //公历节日 *表示放假日
99. sFtv: Array[0..95] of string =(
100. '0101*新年元旦',
101. '0202 世界湿地日',
102. '0207 国际声援南非日',
103. '0210 国际气象节',
104. '0212 国际足球比赛日',
105. '0214 西方情人节',
106. '0301 国际海豹日',
107. '0303 全国爱耳日',
108. '0308 国际妇女节',
109. '0312 植树节 孙中山逝世纪念日',
110. '0314 国际警察日',
111. '0315 国际消费者权益日',
112. '0317 中国国医节 国际航海日',
113. '0321 世界森林日 消除种族歧视国际日',
114. '0321 世界儿歌日',
115. '0322 世界水日',
116. '0323 世界气象日',
117. '0324 世界防治结核病日',
118. '0325 全国中小学生安全教育日',
119. '0330 巴勒斯坦国土日',
120. '0401 愚人节 全国爱国卫生运动月(四月) 税收宣传月(四月)',
121. '0407 世界卫生日',
122. '0422 世界地球日',
123. '0423 世界图书和版权日',
124. '0424 亚非新闻工作者日',
125. '0501*国际劳动节',
126. '0504 中国五四青年节',
127. '0505 碘缺乏病防治日',
128. '0508 世界红十字日',
129. '0512 国际护士节',
130. '0515 国际家庭日',
131. '0517 世界电信日',
132. '0518 国际博物馆日',
133. '0520 全国学生营养日',
134. '0523 国际牛奶日',
135. '0531 世界无烟日',
136. '0601*国际儿童节',
137. '0605 世界环境日',
138. '0606 全国爱眼日',
139. '0617 防治荒漠化和干旱日',
140. '0623 国际奥林匹克日',
141. '0625 全国土地日',
142. '0626 国际反毒品日',
143. '0701 中国共产党建党日 世界建筑日',
144. '0702 国际体育记者日 精品推介站(http://www.21softs.com/)正式对外开放纪念日',
145. '0707 中国人民抗日战争纪念日',
146. '0711 世界人口日',
147. '0730 非洲妇女日',
148. '0801 中国建军节',
149. '0808 中国男子节(爸爸节)',
150. '0815 日本正式宣布无条件投降日',
151. '0908 国际扫盲日 国际新闻工作者日',
152. '0910*教师节',
153. '0914 世界清洁地球日',
154. '0916 国际臭氧层保护日',
155. '0918 九·一八事变纪念日',
156. '0920 国际爱牙日',
157. '0927 世界旅游日',
158. '1001*国庆节 世界音乐日 国际老人节',
159. '1001 国际音乐日',
160. '1002 国际和平与民主自由斗争日',
161. '1004 世界动物日',
162. '1008 全国高血压日',
163. '1008 世界视觉日',
164. '1009 世界邮政日 万国邮联日',
165. '1010 辛亥革命纪念日 世界精神卫生日',
166. '1013 世界保健日 国际教师节',
167. '1014 世界标准日',
168. '1015 国际盲人节(白手杖节)',
169. '1016 世界粮食日',
170. '1017 世界消除贫困日',
171. '1022 世界传统医药日',
172. '1024 联合国日 世界发展信息日',
173. '1031 世界勤俭日',
174. '1107 十月社会主义革命纪念日',
175. '1108 中国记者日',
176. '1109 全国消防安全宣传教育日',
177. '1110 世界青年节',
178. '1111 国际科学与和平周(本日所属的一周)',
179. '1112 孙中山诞辰纪念日',
180. '1114 世界糖尿病日',
181. '1117 国际大学生节 世界学生节',
182. '1121 世界问候日 世界电视日',
183. '1129 国际声援巴勒斯坦人民国际日',
184. '1201 世界艾滋病日',
185. '1203 世界残疾人日',
186. '1205 国际经济和社会发展志愿人员日',
187. '1208 国际儿童电视日',
188. '1209 世界足球日',
189. '1210 世界人权日',
190. '1212 西安事变纪念日',
191. '1213 南京大屠杀(1937年)纪念日!紧记血泪史!',
192. '1221 国际篮球日',
193. '1224 平安夜',
194. '1225*圣诞节',
195. '1229 国际生物多样性日');
196. //某月的第几个星期几。 5,6,7,8 表示到数第 1,2,3,4 个星期几
197. wFtv: Array[0..11] of string = (
198. '0110 黑人日',
199. '0150 世界麻风日', //一月的最后一个星期日(月倒数第一个星期日)
200. '0520 国际母亲节',
201. '0530 全国助残日',
202. '0630 父亲节',
203. '0911 劳动节',
204. '0932 国际和平日',
205. '0940 国际聋人节 世界儿童日',
206. '0950 世界海事日',
207. '1011 国际住房日',
208. '1013 国际减轻自然灾害日(减灾日)',
209. '1144 感恩节');
210. //农历节日
211. lFtv: Array[0..10] of string = (
212. '0101*春节',
213. '0115*元宵节 中国情人节',
214. '0202 龙抬头节',
215. '0323 妈祖生辰 (天上圣母诞辰)',
216. '0505*端午节',
217. '0707 七七中国情人节',
218. '0815*中秋节',
219. '0909*重阳节',
220. '1208 腊八节',
221. '1223 灶君(祭灶)节',
222. '0100*除夕');
223. function lYearDays(y: integer): integer; //返回农历 y年的总天数
224. function leapDays(y: integer): integer; //返回农历 y年闰月的天数
225. function leapMonth(y: integer): integer; //返回农历 y年闰哪个月 1-12 , 没闰返回 0
226. function monthDays(y, m: integer): integer; //返回农历 y年m月的总天数
227. function Lunar(objDate: TDate): THzDate; //算出农历, 传入日期控件, 返回农历日期控件
228. function solarDays(y, m: integer): integer; //返回公历 y年m月的天数
229. function cyclical(num: integer): string; //传入 offset 返回干支, 0=甲子
230. function HzLunar(objDate: THzDate): TDate; //算出公历, 传入农历日期控件, 返回公历
231. function ChkHzDate(objDate: THzDate): Boolean; //检查农历日期是否合法
232. function sTerm(y, n: integer): TDateTime; //某年的第n个节气为几日(从0小寒起算)
233. function GetGZ(y, m: integer; objDate: TDate): TGzDate; //求年柱,月柱,日柱(年,月为农历数字,objDate为当天的公历日期)
234. function GetCnDay(objDate: THzDate): string;
235. function GetCnMonth(ObjDate: THzDate): string;
236. function GetCnYear(objDate: THzDate): string;
237. function GetCnWeek(day: TDate): string;
238. //取得潮汐时间 jth: 潮汐间隙小时,jtm: 潮汐间隙分钟
239. function GetZX(HzDay: Integer; zxjx: TTime= 0.42709491898): string;
240. // 指定月分第几个星期几是第几天
241. function Getd0(y, m: Integer; S: string): Integer;
242. // 去除节日列表中的标记,返回以,相隔的字符串
243. procedure ClearJR(S: string; var strSave: string);
244. //取得指定日期的节日
245. function GetDayOfJR(day: TCnDate):string;
246. // 取得指定日期的节气
247. function GetDayOfJQ(day: TDate): string;
248. implementation
249. {*****************************************************************************
250. 日期计算
251. *****************************************************************************}
252. //====================================== 返回农历 y年的总天数
253. function lYearDays(y: integer): integer;
254. var
255. i, sum: integer;
256. begin
257. sum:= 348;
258. i:= $8000;
259. while i > $8 do
260. begin
261. if (lunarInfo[y - 1900] and i) > 0 then Inc(sum);
262. i:= i shr 1;
263. end;
264. Result:= sum + leapDays(y);
265. end;
266. //====================================== 返回农历 y年闰月的天数
267. function leapDays(y: integer): integer;
268. begin
269. if Boolean(leapMonth(y)) then
270. begin
271. if (lunarInfo[y - 1899] and $f) = $f then Result := 30 else Result := 29;
272. end
273. else Result := 0;
274. end;
275. //====================================== 返回农历 y年闰哪个月 1-12 , 没闰返回 0
276. function leapMonth(y: integer): integer;
277. var
278. lm: Word;
279. begin
280. lm:= lunarInfo[y - 1900] and $f;
281. if lm = $f then Result:= 0 else Result:= lm;
282. end;
283. //====================================== 返回农历 y年m月的总天数
284. function monthDays(y, m: integer): integer;
285. var
286. temp1, temp2, temp3: Word;
287. begin
288. temp1:= lunarInfo[y - 1900];
289. temp2:= $8000;
290. if m > 1 then temp2:= $8000 shr (m - 1);
291. // temp2:= $10000 shr (m - 1);
292. temp3:= temp1 and temp2;
293. // if Boolean(temp3) then
294. // if Boolean(lunarInfo[y - 1900] and ($8000 shr (m - 1))) then
295. if temp3 > 0 then
296. Result:= 30
297. else Result:= 29;
298. end;
299. //====================================== 算出农历, 传入日期控件, 返回农历日期控件
300. function Lunar(objDate: TDate): THzDate;
301. var
302. i, leap, temp, offset: integer;
303. begin
304. temp:= yearof(objDate);
305. if (temp < 1901) or (temp > 2100) then exit;
306. offset:= DaysBetween(EncodeDate(1900,1,31),objDate);
307. i:= 1900;
308. while (i < 2100) and (offset > 0) do
309. begin
310. temp:= lYearDays(i);
311. offset:= offset - temp;
312. Inc(i);
313. end;
314. if (offset < 0) then
315. begin
316. offset:= offset + temp;
317. i:= i - 1;
318. end;
319. Result.Year:= i;
320. leap:= leapMonth(i); //闰哪个月
321. Result.isLeap:= False;
322. i:=1;
323. while (i < 13) and (offset > 0) do
324. begin
325. if (leap > 0) and (i = leap + 1) and (Result.isLeap = False) then
326. begin
327. i:= i - 1;
328. Result.isLeap:= True;
329. temp:= leapDays(Result.Year);
330. end else temp:= monthDays(Result.Year, i);
331. if (Result.isLeap = True) and (i = leap + 1) then
332. Result.isLeap:= False;
333. offset:= offset - temp;
334. inc(i);
335. end;
336. if (offset = 0) and (leap > 0) and (i = leap + 1) then
337. begin
338. if Result.isLeap then Result.isLeap:= False
339. else begin
340. Result.isLeap:= True;
341. i:= i - 1;
342. end;
343. end;
344. if offset < 0 then
345. begin
346. offset:= offset + temp;
347. i:= i - 1;
348. end;
349. Result.Month:= i;
350. Result.Day:= offset + 1;
351.
352. end;
353. //=============================== // 求年柱,月柱,日柱
354. //============= 年,月为农历数字,objDate为当天的公历日期
355. function GetGZ(y, m: integer; objDate: TDate): TGzDate;
356. var
357. term: TDate;
358. sy, sm, sd: Word;
359. begin
360. DecodeDate(objDate, sy, sm, sd);
361. term:= sTerm(sy, (sm - 1) * 2); // 当月的节气日期
362. //年柱 1900年立春后为庚子年(60进制36)
363. Result.Year:= sy - 1900 + 36;
364. //依立春日期调整年柱
365. if (sm = 2) and (objDate < term) then
366. Result.Year:= sy - 1900 + 35;
367. //月柱 农历1900年1月小寒以前为 丙子月(60进制12)
368. Result.Month:= (sy - 1900) * 12 + sm + 11;
369. //依节气调整月柱
370. if objDate >= DateOf(term) then Result.Month:= (sy - 1900) * 12 + sm + 12;
371. // 1900/1/1 日柱为甲辰日(60进制10)
372. Result.Day:= DaysBetween(EncodeDate(1900,1,1),objDate) + 10;
373. end;
374. //====================================== 算出公历, 传入农历日期控件, 返回公历
375. function HzLunar(objDate: THzDate): TDate;
376. var
377. i, j, t, leap, temp, offset: integer;
378. isLeap: Boolean;
379. y, m: integer;
380. begin
381. Result:= EncodeDate(1,1,1);
382. if not ChkHzDate(objDate) then exit;
383. isLeap:= False;
384. y:= objDate.Year;
385. m:= objDate.Month;
386. leap:= leapMonth(y);
387. //本年内从大年初一过来的天数
388. offset:= 0;
389. i:= 1;
390. while i < m do
391. begin
392. if i = leap then
393. begin
394. if isLeap then
395. begin
396. temp:= leapDays(y);
397. isLeap:= False;
398. end else
399. begin
400. temp:= monthDays(y, i);
401. isLeap:= True;
402. i:= i - 1;
403. end;
404. end else
405. temp:= monthDays(y, i);
406. offset:= offset + temp;
407. Inc(i);
408. end;
409. offset:= offset + objDate.Day - 1;
410. if (m = leap) and objDate.isLeap then //若为闰月,再加上前一个非闰月天数
411. offset:= offset + monthDays(y, m);
412. // 该年到 2000.1.1 这几年的天数
413. if y > 2000 then
414. begin
415. i:= 2000;
416. j:= y - 1;
417. end else
418. begin
419. i:= y;
420. j:= 1999;
421. end;
422. temp:= 0;
423. for t:= i to j do
424. begin
425. temp:= temp + lYearDays(t);
426. end;
427. if y > 1999 then offset:= offset + temp
428. else offset:= offset - temp;
429. //农历二零零零年大年初一的阳历为 2000.2.5
430. Result:= incDay(EncodeDate(2000,2,5),offset);
431. end;
432. //====================================== 检查农历日期是否合法
433. function ChkHzDate(objDate: THzDate): Boolean;
434. begin
435. if (objDate.Year > 2099) or (objDate.Year < 1901)
436. or (objDate.Month > 12) or (objDate.Day > 31) then
437. begin
438. Result:= False;
439. exit;
440. end;
441. Result:= True;
442. if objDate.isLeap then
443. begin
444. if leapMonth(objDate.Year) = objDate.Month then
445. begin
446. if leapDays(objDate.Year) < objDate.Day then
447. Result:= False;
448. end else Result:= False;
449. end else
450. begin
451. if monthDays(objDate.Year,objDate.Month) < objDate.Day then
452. Result:= False;
453. end;
454. end;
455. //===== 某年的第n个节气为几日(从0小寒起算)
456. function sTerm(y, n: integer): TDateTime;
457. var
458. temp: TDateTime;
459. t,tt: real;
460. i: Int64;
461. begin
462. t:= sTermInfo[n];
463. t:= t * 60000;
464. tt:= 31556925974.7 * (y - 1900);
465. t:= t + tt;
466. i:= Round(t);
467. Temp:= IncMilliSecond(EncodeDateTime(1900,1,6,2,5,0,0),i);
468. Result:= temp;
469. { var offDate = new Date( ( 31556925974.7*(y-1900) + sTermInfo[n]*60000 ) + Date.UTC(1900,0,6,2,5) );
470. return(offDate.getUTCDate());
471. }
472. end;
473.
474. //==============================返回公历 y年m月的天数
475. function solarDays(y, m: integer): integer;
476. begin
477. if m = 2 then
478. begin
479. if ((y mod 4) = 0) and ((y mod 100) <> 0) or ((y mod 400) = 0) then
480. Result:= 29
481. else Result:= 28;
482. end else Result:= solarMonth[m - 1];
483. end;
484. //============================== 传入 offset 返回干支, 0=甲子
485. function cyclical(num: integer): string;
486. begin
487. Result:= Gan[num mod 10] + Zhi[num mod 12];
488. end;
489. //
490. function GetCnDay(objDate: THzDate): string;
491. var
492. day: integer;
493. begin
494. day:= objDate.Day;
495. case day of
496. 1..10: Result:= nStr2[0] + nStr1[day];
497. 11..19: Result:= nStr2[1] + nStr1[day - 10];
498. 20: Result:= nStr1[2] + nStr1[10];
499. 21..29: Result:= nStr2[2] + nStr1[day - 20];
500. 30: Result:= nStr1[3] + nStr1[10];
501. end;
502. end;
503. function GetCnMonth(ObjDate: THzDate): string;
504. var
505. month: integer;
506. begin
507. month:= objDate.Month;
508. case month of
509. 1..10: Result:= nStr1[month];
510. 11..12: Result:= nStr1[10] + nStr1[month - 10];
511. end;
512. if objDate.isLeap then Result:= '闰' + Result;
513. Result:= Result + '月';
514. end;
515. function GetCnYear(objDate: THzDate): string;
516. var
517. year, temp: integer;
518. zero: string;
519. begin
520. year:= objDate.Year;
521. zero:= '零';
522. temp:= year div 1000;
523. Result:= nStr1[temp];
524. year:= year - temp * 1000;
525. if year >= 100 then
526. begin
527. temp:= year div 100;
528. Result:= Result + nStr1[temp];
529. year:= year - temp * 100;
530. end
531. else
532. Result:= Result + zero;
533. if year >= 10 then
534. begin
535. temp:= year div 10;
536. Result:= Result + nStr1[temp];
537. year:= year - temp * 10;
538. end
539. else
540. Result:= Result + zero;
541. if year = 0 then Result:= Result + zero else
542. Result:= Result + nStr1[year];
543. Result:= Result + '年';
544. end;
545. // 潮汐算法主要参考自: <http://www.yuqu.com/haidiao/hai019.htm>
546. //
547. // 第一次高潮 F1= 0.8 X ((day mod 15) - 1) + 高潮间隙
548. // 低潮 F2= F1 + 6:12
549. // 第二次高潮 F3= F2 + 12:24 - 6:12
550. function GetZX(HzDay: Integer; zxjx: TTime= 0.42709491898): string;
551. var
552. Pos: Integer;
553. temp: Double;
554. h, m: Word;
555. begin
556. if zxjx = 0 then zxjx:= 0.42709491898;
557. Pos:= HzDay mod 15;
558. if Pos = 0 then Pos:= 15;
559. Inc(Pos, -1);
560. temp:= 0.8 * Pos;
561. h:= Trunc(temp);
562. m:= Trunc((temp - h) * 10);
563. m:= 60 * h + m * 6;
564. zxjx:= IncMinute(zxjx, m);
565. Result:= FormatDateTime(' hh:mm',zxjx); //高潮,低潮间隔是二个#32空格
566. zxjx:= IncMinute(zxjx, 372);
567. Result:= Result + FormatDateTime(' hh:mm',zxjx);
568. zxjx:= IncMinute(zxjx, 372);
569. Result:= Result + FormatDateTime(' hh:mm',zxjx);
570. end;
571. // 指定月分第几个星期几是第几天
572. function Getd0(y, m: Integer; S: string): Integer;
573. var
574. cntDay, cntWeek, idxPos, idxWeek: integer;
575. CurDay: TDate;
576. i: integer;
577. begin
578. cntDay:= solarDays(y, m);
579. idxPos:= strtoint(Copy(S,1,1));
580. idxWeek:= strtoint(Copy(S,2,1));
581. cntWeek:= 1;
582. if idxPos< 5 then
583. begin
584. CurDay:= EncodeDate(y, m, 1);
585. for i:= 1 to cntDay do
586. begin
587. if (DayOfWeek(CurDay) - 1) = idxWeek then
588. if cntWeek = idxPos then break else Inc(cntWeek);
589. CurDay:= IncDay(CurDay);
590. end;
591. Result:= i;
592. end
593. else begin
594. idxPos:= idxPos - 4;
595. CurDay:= EncodeDate(y, m, cntDay);
596. for i:= cntDay downto 1 do
597. begin
598. if (DayOfWeek(CurDay) - 1) = idxWeek then
599. if cntWeek = idxPos then break else Inc(cntWeek);
600. CurDay:= IncDay(CurDay, -1);
601. end;
602. Result:= i;
603. end;
604. end;
605. // 去除节日列表中的标记,返回以,相隔的字符串
606. procedure ClearJR(S: string; var strSave: string);
607. var
608. PosOfSpc: Integer;
609. ss: string;
610. begin
611. s:= Trim(s);
612. repeat
613. PosOfSpc:= Pos(' ', S);
614. if PosOfSpc > 0 then ss:= Copy(s, 1, PosOfSpc -1)
615. else ss:= s;
616. ss:= TrimLeft(ss);
617. if Copy(ss,1,1) = '*' then Delete(ss,1,1);
618. if strSave = '' then strSave:= ss
619. else strSave:= strSave + ',' + ss;
620. Delete(s, 1, PosOfSpc);
621. until PosOfSpc = 0;
622. end;
623. // 取得指定日期的节气
624. function GetDayOfJQ(day: TDate): string;
625. var
626. jq: Integer;
627. term: TDateTime;
628. begin
629. Result:= '';
630. jq:= (MonthOf(day) - 1) * 2;
631. term:= sTerm(Yearof(day), jq); //节气时间
632. if DateOf(term) = day then Result:= solarTerm[jq]
633. else
634. begin
635. term:= sTerm(Yearof(day), jq + 1); //中气时间
636. if DateOf(term) = day then Result:= solarTerm[jq+1];
637. end;
638. if Result<>'' then
639. Result:= Result + ' (时间:' + FormatDateTime('hh:mm',term) + ')';
640. end;
641.
642. //取得指定日期的节日
643. function GetDayOfJR(day: TCnDate):string;
644. var
645. H: THzDate;
646. i: Integer;
647. y, m, d: Word;
648. m0, d0: Integer;
649. lm: Boolean;
650. s, strSave: string;
651. begin
652. strSave:= '';
653. //农历节日
654. H:= day.HzDate;
655. m:= H.Month;
656. lm:= H.isLeap;
657. d:= H.Day;
658. if not lm then
659. for i:= Low(lFtv) to High(lFtv) do
660. begin
661. m0:= strtoint(Copy(lFtv[i], 1, 2));
662. d0:= strtoint(Copy(lFtv[i],3,2));
663. if (m0 = m) and (d0 = d) then
664. begin
665. s:= lFtv[i];
666. Delete(s,1,4);
667. ClearJR(s,strSave);
668. end;
669. end;
670. //公历节日
671. DecodeDate(day.Date, y, m, d);
672. for i:= Low(sFtv) to High(sFtv) do
673. begin
674. m0:= strtoint(sFtv[i][1] + sFtv[i][2]);
675. d0:= strtoint(sFtv[i][3] + sFtv[i][4]);
676. if (m0 = m) and (d0 = d) then
677. begin
678. S:= sFtv[i];
679. Delete(S,1,4);
680. ClearJr(s,strSave);
681. end;
682. end;
683. for i:= Low(wFtv) to High(wFtv) do
684. begin
685. m0:= strtoint(Copy(wFtv[i],1,2));
686. if m0 = m then
687. begin
688. d0:= Getd0(y, m, Copy(wFtv[i],3,2));
689. if (d0 = d) then
690. begin
691. S:= wFtv[i];
692. Delete(S, 1, 4);
693. ClearJR(s,strSave);
694. end;
695. end;
696. end;
697. Result:= strSave;
698. end;
699. function GetCnWeek(day: TDate): string;
700. begin
701. Result:= '星期' + nStr1[DayOfWeek(day) - 1]
702. end;
703. end.
計算該日期當月的天數
自訂函數做法如下:
function LastDay(xDate: TDate): Word;
var
Y, M , D: Word;
const aMonthLastDay: array[1..12] of word
=(31,28,31,30,31,30,31,31,30,31,30,31);
begin
DecodeDate(xDate, Y, M, D);
if Y mod 4 = 0 then
aMonthLastDay[2] := 29
else
aMonthLastDay[2] := 28;
result := aMonthLastDay[M];
end;
計算天數不包含六日
use...... DateUtils
function StartOfTheMonth(const A Value: TDateTime):TDateTime;該月起始日期
function EndOfTheMonth(const A Value: TDateTime):TDateTime;該月結束日期
function DaysInMonth(const A Value: TDateTime):word;該月有幾天
配合 function DayOfWeek(const A Value: TDateTime):word;
寫個迴圈就可計算出來了
例如要計算以今天為準當月有幾天不含六、日
var i,j :integer;
mydate :TDateTime;
.
.
j:=0;
mydate:=StartOfTheMonth(date());
for i:=1 to DaysInMonth(date()) do begin
if (DayOfWeek(mydate)<>1)and(DayOfWeek(mydate)<>7) then begin
j:=j+1;
end;
mydate:=mydate+1;
end;
function StartOfTheMonth(const A Value: TDateTime):TDateTime;該月起始日期
function EndOfTheMonth(const A Value: TDateTime):TDateTime;該月結束日期
function DaysInMonth(const A Value: TDateTime):word;該月有幾天
配合 function DayOfWeek(const A Value: TDateTime):word;
寫個迴圈就可計算出來了
例如要計算以今天為準當月有幾天不含六、日
var i,j :integer;
mydate :TDateTime;
.
.
j:=0;
mydate:=StartOfTheMonth(date());
for i:=1 to DaysInMonth(date()) do begin
if (DayOfWeek(mydate)<>1)and(DayOfWeek(mydate)<>7) then begin
j:=j+1;
end;
mydate:=mydate+1;
end;
2009年7月8日 星期三
HP大中華區總裁 / 孫振耀 退休感言
HP大中華區總裁 / 孫振耀 退休感言 (長) — 勵志啊 !
一、關於工作與生活
我有個有趣的觀察,外企公司多的是25-35歲的白領,40歲以上的員工很少,二三十歲的外企員工是意氣風發的,但外企公司40歲附近的經理人是很尷尬的。我見過的40歲附近的外企經理人大多在一直跳槽,最後大多跳到民企,比方說,唐駿。外企員工的成功很大程度上是公司的成功,並非個人的成功,西門子的確比國美大,但並不代表西門子中國經理比國美的老闆強,甚至可以說差得很遠。而進外企的人往往並不能很早理解這一點,把自己的成功90%歸功於自己的能力,實際上,外企公司隨便換個中國區總經理並不會給業績帶來什麼了不起的影響。好了問題來了,當這些經理人40多歲了,他們的薪資要求變得很高,而他們的才能其實又不是那麼出眾,作為外企公司的老闆,你會怎麼選擇?有的是只要不高薪水的,要出位的精明強幹精力沖沛的年輕人,有的是,為什麼還要用你?
從上面這個例子,其實可以看到我們的工作軌跡,二三十歲的時候,生活的壓力還比較小,身體還比較好,上面的父母身體還好,下面又沒有孩子,不用還房貸,也沒有孩子要上大學,當個外企小白領還是很光鮮的,掙得不多也夠花了。但是人終歸要結婚生子,終歸會老,到了40歲,父母老了,要看病要吃藥,要有人看護,自己要還房貸,要過基本體面的生活,要養小孩……那個時候需要掙多少錢才夠花才重要。所以,看待工作,眼光要放遠一點,一時的誰高誰低並不能說明什麼。
從這個角度上來說,我不太贊成過於關注第一份工作的薪水,更沒有必要攀比第一份工作的薪水,這在剛剛出校園的學生中間是很常見的。正常人大概要工作 35年,這好比是一場馬拉松比賽,和真正的馬拉松比賽不同的是,這次比賽沒有職業選手,每個人都只有一次機會。要知到,有很多人甚至堅持不到終點,大多數人最後是走到終點的,只有少數人是跑過終點的,因此在剛開始的時候,去搶領先的位置並沒有太大的意義。剛進社會的時候如果進500強公司,大概能拿到3k -6k/月的工資,有些特別技術的人才可能可以到8k/月,可問題是,5年以後拿多少?估計5k-10k了不起了。起點雖然高,但增幅有限,而且,後面的年輕人追趕的壓力越來越大。
我前兩天問我的一個銷售,你會的這些東西一個新人2年就都學會了,但新人所要求的薪水卻只是你的一半,到時候,你怎麼辦?
職業生涯就像一場體育比賽,有初賽、復賽、決賽。初賽的時候大家都剛剛進社會,大多數都是實力一般的人,這時候努力一點認真一點很快就能讓人脫穎而出,於是有的人二十多歲做了經理,有的人遲些也終於贏得了初賽,三十多歲成了經理。然後是復賽,能參加復賽的都是贏得初賽的,每個人都有些能耐,在聰明才智上都不成問題,這個時候再想要勝出就不那麼容易了,單靠一點點努力和認真還不夠,要有很強的堅忍精神,要懂得靠團隊的力量,要懂得收服人心,要有長遠的眼光……
看上去贏得復賽並不容易,但,還不是那麼難。因為這個世界的規律就是給人一點成功的同時、讓人驕傲自滿,剛剛贏得初賽的人往往不知道自己贏得的僅僅是初賽,有了一點小小的成績大多數人都會驕傲自滿起來,認為自己已經懂得了全部,不需要再努力再學習了,他們會認為之所以不能再進一步已經不是自己的原因了。雖然他們仍然不好對付,但是他們沒有耐性,沒有容人的度量,更沒有清晰長遠的目光。就像一隻憤怒的鬥牛,雖然猛烈,最終是會敗的,而贏得復賽的人則象鬥牛士一樣,不急不躁,跟隨著自己的節拍,慢慢耗盡對手的耐心和體力。贏得了復賽以後,大約已經是一位很了不起的職業經理人了,當上了中小公司的總經理,大公司的副總經理,主管著每年幾千萬乃至幾億的生意。
最終的決賽來了,說實話我自己都還沒有贏得決賽,因此對於決賽的決勝因素也只能憑自己的猜測而已,這個時候的輸贏或許就像武俠小說裏寫得那樣,大家都是高手,只能等待對方犯錯了,要想輕易擊敗對手是不可能的,除了使上渾身解數,還需要一點運氣和時間。世界的規律依然發揮著作用,贏得復賽的人已經不只是驕傲自滿了,他們往往剛愎自用,聽不進去別人的話,有些人的脾氣變得暴躁,心情變得浮躁,身體變得糟糕,他們最大的敵人就是他們自己,在決賽中要做的只是不被自己擊敗,等著別人被自己擊敗。這和體育比賽是一樣的,最後高手之間的比賽,就看誰失誤少誰就贏得了決賽。
二、 根源
你工作快樂嗎?你的工作好嗎?
有沒有覺得幹了一段時間以後工作很不開心?有沒有覺得自己入錯了行?有沒有覺得自己沒有得到應有的待遇?有沒有覺得工作像一團亂麻每天上班都是一種痛苦?有沒有很想換個工作?有沒有覺得其實現在的公司並沒有當初想像得那麼好?有沒有覺得這份工作是當初因為生存壓力而找的,實在不適合自己?你從工作中得到你想要得到的了麼?你每天開心麼?
天涯上憤怒的人很多,你有沒有想過,你為什麼不快樂?你為什麼憤怒?
其實,你不快樂的根源,是因為你不知道要什麼!你不知道要什麼,所以你不知道去追求什麼,你不知道追求什麼,所以你什麼也得不到。
我總覺得,職業生涯首先要關注的是自己,自己想要什麼?大多數人大概沒想過這個問題,唯一的想法只是——我想要一份工作,我想要一份不錯的薪水,我知道所有人對於薪水的渴望,可是,你想每隔幾年重來一次找工作的過程麼?你想每年都在這種對於工作和薪水的焦急不安中度過麼?不想的話,就好好想清楚。飲鴆止渴,不能因為口渴就拼命喝毒藥。越是焦急,越是覺得自己需要一份工作,越饑不擇食,越想不清楚,越容易失敗,你的經歷越來越差,下一份工作的人看著你的簡歷就皺眉頭。於是你越喝越渴,越渴越喝,陷入惡性循環。最終只能哀歎世事不公或者生不逢時,只能到天涯上來發洩一把,在失敗者的共鳴當中尋求一點心理平衡罷了。大多數人都有生存壓力,我也是,有生存壓力就會有很多焦慮,積極的人會從焦慮中得到動力,而消極的人則會因為焦慮而迷失方向。所有人都必須在壓力下做出選擇,這就是世道,你喜歡也罷不喜歡也罷。
一般我們處理的事情分為重要的事情和緊急的事情,如果不做重要的事情就會常常去做緊急的事情。比如鍛煉身體保持健康是重要的事情,而看病則是緊急的事情。如果不鍛煉身體保持健康,就會常常為了病痛煩惱。又比如防火是重要的事情,而救火是緊急的事情,如果不注意防火,就要常常救火。找工作也是如此,想好自己究竟要什麼是重要的事情,找工作是緊急的事情,如果不想好,就會常常要找工作。往往緊急的事情給人的壓力比較大,迫使人們去趕緊做,相對來說重要的事情反而沒有那麼大的壓力,大多數人做事情都是以壓力為導向的,壓力之下,總覺得非要先做緊急的事情,結果就是永遠到處救火,永遠沒有停歇的時候。(很多人的工作也像是救火隊一樣忙碌痛苦,也是因為工作中沒有做好重要的事情。)那些說自己活在水深火熱為了生存顧不上那麼多的朋友,今天找工作困難是當初你們沒有做重要的事情,是結果不是原因。如果今天你們還是因為急於要找一份工作而不去思考,那麼或許將來要繼續承受痛苦找工作的結果。
我始終覺得我要說的話題,沉重了點,需要很多思考,遠比唐笑打武警的話題來的枯燥乏味,但是,天下沒有輕鬆的成功,成功,要付代價。請先忘記一切的生存壓力,想想這輩子你最想要的是什麼?所以,最要緊的事情,先想好自己想要什麼。
三、什麼是好工作
當初微軟有個唐駿,很多大學裏的年輕人覺得這才是他們嚮往的職業生涯,我在清華bbs裏發的帖子被這些學子們所不屑,那個時候學生們只想出國或者去外企,不過如今看來,我還是對的,唐駿去了盛大,陳天橋創立的盛大,一家民營公司。一個高學歷的海歸在500強的公司裏拿高薪水,這大約是很多年輕人的夢想,問題是,每年畢業的大學生都在做這個夢,好的職位卻只有500個。
人都是要面子的,也是喜歡攀比的,即使在工作上也喜歡攀比,不管那是不是自己想要的。大家認為外企公司很好,可是好在哪里呢?好吧,他們在比較好的寫字樓,這是你想要的麼?他們出差住比較好的酒店,這是你想要的麼?別人會羡慕一份外企公司的工作,這是你想要的麼?那一切都是給別人看的,你幹嗎要活得那麼辛苦給別人看?另一方面,他們薪水福利一般,並沒有特別了不起,他們的晉升機會比較少,很難做到很高階的主管,他們雖然厭惡常常加班,卻不敢不加班,因為“你不幹有得是人幹”,大部分情況下會找個臺灣人香港人新加坡人來管你,而這些人又往往有些莫名其妙的優越感。你想清楚了麼?500強一定好麼?找工作究竟是考慮你想要什麼,還是考慮別人想看什麼?
我的大學同學們大多數都到美國了,甚至畢業這麼多年了,還有人最近到國外去了。出國真的有那麼好麼?我的大學同學們,大多數還是在博士、博士後、訪問學者地掙扎著,至今只有一個正經在一個美國大學裏拿到個正式的教職。國內的教授很難當麼?我有幾個表親也去了國外了,他們的父母獨自在國內,沒有人照顧,有好幾次人在家裏昏倒都沒人知道,出國,真的這麼光彩麼?就像有人說的“很多事情就像看A片,看的人覺得很爽,做的人未必。”
人總想找到那個最好的,可是,什麼是最好的?你覺得是最好的那個,是因為你的確瞭解,還是因為別人說他是最好的?即使他對於別人是最好的,對於你也一定是最好的麼?
對於自己想要什麼,自己要最清楚,別人的意見並不是那麼重要。很多人總是常常被別人的意見所影響,親戚的意見,朋友的意見,同事的意見……問題是,你究竟是要過誰的一生?人的一生不是父母一生的續集,也不是兒女一生的前傳,更不是朋友一生的外篇,只有你自己對自己的一生負責,別人無法也負不起這個責任。自己做的決定,至少到最後,自己沒什麼可後悔。對於大多數正常智力的人來說,所做的決定沒有大的對錯,無論怎麼樣的選擇,都是可以嘗試的。比如你沒有考自己上的那個學校,沒有入現在這個行業,這輩子就過不下去了?就會很失敗?不見得。
我想,好工作,應該是適合你的工作,具體點說,應該是能給你帶來你想要的東西的工作,你或許應該以此來衡量你的工作究竟好不好,而不是拿公司的大小,規模,外企還是國企,是不是有名,是不是上市公司來衡量。小公司,未必不是好公司,賺錢多的工作,也未必是好工作。你還是要先弄清楚你想要什麼,如果你不清楚你想要什麼,你就永遠也不會找到好工作,因為你永遠只看到你得不到的東西,你得到的,都是你不想要的。
可能,最好的,已經在你的身邊,只是,你還沒有學會珍惜。人們總是盯著得不到的東西,而忽視了那些已經得到的東西。
四、普通人
我發現中國人的勵志和國外的勵志存在非常大的不同,中國的勵志比較鼓勵人立下大志願,臥薪嚐膽,有朝一日成富成貴。而國外的勵志比較鼓勵人勇敢面對現實生活,面對普通人的困境,雖然結果也是成富成貴,但起點不一樣,相對來說,我覺得後者在操作上更現實,而前者則需要用999個失敗者來堆砌一個成功者的故事。
我們都是普通人,普通人的意思就是,概率這件事是很準的。因此,我們不會買彩票中500萬,我們不會成為比爾蓋茨或者李嘉誠,我們不會坐飛機掉下來,我們當中很少的人會創業成功,我們之中有30%的人會離婚,我們之中大部分人會活過65歲……
所以請你在想自己要什麼的時候,要得“現實”一點,你說我想要做李嘉誠,抱歉,我幫不上你。成為比爾蓋茨或者李嘉誠這種人,是靠命的,看我寫的這篇文章絕對不會讓你成為他們,即使你成為了他們,也絕對不是我這篇文章的功勞。“王侯將相甯有種乎”但真正當皇帝的只有一個人,王侯將相,人也不多。目標定得高些對於喜歡挑戰的人來說有好處,但對於大多數普通人來說,反而比較容易灰心沮喪,很容易就放棄了。
回過頭來說,李嘉誠比你有錢大致50萬倍,他比你更快樂麼?或許。有沒有比你快樂50萬倍,一定沒有。他比你最多也就快樂一兩倍,甚至有可能還不如你快樂。尋找自己想要的東西不是和別人比賽,比誰要得更多更高,比誰的目標更遠大。雖然成為李嘉誠這個目標很宏大,但你並不見得會從這個目標以及追求目標的過程當中獲得快樂,而且基本上你也做不到。你必須聽聽你內心的聲音,尋找真正能夠使你獲得快樂的東西,那才是你想要的東西。
你想要的東西,或者我們把它稱之為目標,目標其實並沒有高低之分,你不需要因為自己的目標沒有別人遠大而不好意思,達到自己的目標其實就是成功,成功有大有小,快樂卻是一樣的。我們追逐成功,其實追逐的是成功帶來的快樂,而非成功本身。職業生涯的道路上,我們常常會被攀比的心態蒙住眼睛,忘記了追求的究竟是什麼,忘記了是什麼能使我們更快樂。
社會上一夜暴富的新聞很多,這些消息,總會在我們的心裏面掀起很多漣漪,漣漪多了就變成驚濤駭浪,心裏的驚濤駭浪除了打翻承載你目標的小船,並不會使得你也一夜暴富。“只見賊吃肉,不見賊挨揍。”我們這些普通人既沒有當賊的勇氣,又缺乏當賊的狠辣絕決,雖然羡慕吃肉,卻更害怕挨揍,偶爾看到幾個沒挨揍的賊就按奈不住,或者心思活動,或者大感不公,真要叫去做賊,卻也不敢。
我還是過普通人的日子,要普通人的快樂,至少,晚上睡得著覺。
五、跳槽與積累
首先要說明,工作是一件需要理智的事情,所以不要在工作上耍個性,天涯上或許會有人覺得你很有個性而叫好,煤氣公司電話公司不會因為覺得你很有個性而免了你的帳單。當你很帥地炒掉了你的老闆,當你很酷地挖苦了一番招聘的HR,帳單還是要照付,只是你賺錢的時間更少了,除了你自己,沒人受損失。
我並不反對跳槽,但跳槽決不是解決問題的辦法,而且頻繁跳槽的後果是讓人覺得沒有忠誠度可言,而且不能安心工作。現在很多人從網上找工作,很多找工作的網站常常給人出些餿主意,要知道他們是盈利性企業,當然要從自身盈利的角度來考慮,大家越是頻繁跳槽頻繁找工作他們越是生意興隆,所以鼓動人們跳槽是他們的工作。所以他們會常常告訴你,你拿的薪水少了,你享受的福利待遇差了,又是“薪情快報”又是“讚歎自由奔放的靈魂”。至於是否會因此讓你不能安心,你跳了槽是否解決問題,是否更加開心,那個,他們管不著。
要跳槽肯定是有問題,一般來說問題發生了,躲是躲不開的,很多人跳槽是因為這樣或者那樣的不開心,如果這種不開心,在現在這個公司不能解決,那麼在下一個公司多半也解決不掉。你必須相信,90%的情況下,你所在的公司並沒有那麼爛,你認為不錯的公司也沒有那麼好。就像圍城裏說的,“城裏的人拼命想衝出來,而城外的人拼命想衝進去。”每個公司都有每個公司的問題,沒有問題的公司是不存在的。換個環境你都不知道會碰到什麼問題,與其如此,不如就在當下把問題解決掉。很多問題當你真的想要去解決的時候,或許並沒有那麼難。有的時候你覺得問題無法解決,事實上,那只是“你覺得”。
人生的曲線應該是曲折向上的,偶爾會遇到低谷但大趨勢總歸是曲折向上的,而不是象脈衝波一樣每每回到起點,我見過不少面試者,30多歲了,四五份工作經歷,每次多則3年,少則1年,30多歲的時候回到起點從一個初級職位開始幹起,拿基本初級的薪水,和20多歲的年輕人一起競爭,不覺得有點辛苦麼?這種日子好過麼?
我非常不贊成在一個行業超過3年以後換行業,基本上,35歲以前我們的生存資本靠打拼,35歲以生存的資本靠的就是積累,這種積累包括人際關係,經驗,人脈,口碑……如果常常更換行業,代表幾年的積累付之東流,一切從頭開始,如果換了兩次行業,35歲的時候大概只有5年以下的積累,而一個沒有換過行業的人至少有了10年的積累,誰會佔優勢?工作到2-3年的時候,很多人覺得工作不順利,好像到了一個瓶頸,心情煩悶,就想辭職,乃至換一個行業,覺得這樣所有一切煩惱都可以拋開,會好很多。其實這樣做只是讓你從頭開始,到了時候還是會發生和原來行業一樣的困難,熬過去就向上跨了一大步,要知道每個人都會經歷這個過程,每個人的職業生涯中都會碰到幾個瓶頸,你熬過去了而別人沒有熬過去你就領先了。跑長跑的人會知道,開始的時候很輕鬆,但是很快會有第一次的難受,但過了這一段又能跑很長一段,接下來會碰到第二次的難受,堅持過了以後又能跑一段,如此往復,難受一次比一次厲害,直到堅持不下去了。大多數人第一次就堅持不了了,一些人能堅持到第二次,第三次雖然大家都堅持不住了,可是跑到這裏的人也沒幾個了,這點資本足夠你安穩活這一輩子了。
一份工作到兩三年的時候,大部分人都會變成熟手,這個時候往往會陷入不斷的重複,有很多人會覺得厭倦,有些人會覺得自己已經搞懂了一切,從而懶得去尋求進步了。很多時候的跳槽是因為覺得失去興趣了,覺得自己已經完成比賽了。其實這個時候比賽才剛剛開始,工作兩三年的人,無論是客戶關係,人脈,手下,和領導的關係,在業內的名氣……還都是遠遠不夠的,但稍有成績的人總是會自我感覺良好的,每個人都覺得自己跟客戶關係鐵得要命,覺得自己在業界的口碑好得很。其實可以肯定地說,一定不是,這個時候,還是要拿出前兩年的幹勁來,穩紮穩打,積累才剛剛開始。
你足夠瞭解你的客戶嗎?你知道他最大的煩惱是什麼嗎?你足夠瞭解你的老闆麼?你知道他最大的煩惱是什麼嗎?你足夠瞭解你的手下麼?你知道他最大的煩惱是什麼嗎?如果你不知道,你憑什麼覺得自己已經積累夠了?如果你都不瞭解,你怎麼能讓他們幫你的忙,做你想讓他們做的事情?如果他們不做你想讓他們做的事情,你又何來的成功?
六、等待
這是個浮躁的人們最不喜歡的話題,本來不想說這個話題,因為會引起太多的爭論,而我又無意和人爭論這些,但是考慮到對於職業生涯的長久規劃,這是一個躲避不了的話題,還是決定寫一寫,不愛看的請離開吧。
並不是每次穿紅燈都會被汽車撞,並不是每個罪犯都會被抓到,並不是每個錯誤都會被懲罰,並不是每個貪官都會被槍斃,並不是你的每一份努力都會得到回報,並不是你的每一次堅持都會有人看到,並不是你每一點付出都能得到公正的回報,並不是你的每一個善意都能被理解……這個,就是世道。好吧,世道不夠好,可是,你有推翻世道的勇氣麼?如果沒有,你有更好的解決辦法麼?有很多時候,人需要一點耐心,一點信心。每個人總會輪到幾次不公平的事情,而通常,安心等待是最好的辦法。
有很多時候我們需要等待,需要耐得住寂寞,等待屬於你的那一刻。周潤發等待過,劉德華等待過,周星馳等待過,王菲等待過,張藝謀也等待過……看到了他們如今的功成名就的人,你可曾看到當初他們的等待和耐心?你可曾看到金馬獎影帝在街邊擺地攤?你可曾看到德雲社一群人在劇場裏給一位觀眾說相聲?你可曾看到周星馳的角色甚至連一句臺詞都沒有?每一個成功者都有一段低沉苦悶的日子,我幾乎能想像得出來他們借酒澆愁的樣子,我也能想像得出他們為了生存而掙扎的窘迫。在他們一生最中燦爛美好的日子裏,他們渴望成功,但卻兩手空空,一如現在的你。沒有人保證他們將來一定會成功,而他們的選擇是耐住寂寞。如果當時的他們總念叨著“成功只是屬於特權階級的”,你覺得他們今天會怎樣?
曾經我也不明白有些人為什麼並不比我有能力卻要坐在我的頭上,年紀比我大就一定要當我的領導麼?為什麼有些爛人不需要努力就能賺錢?為什麼剛剛改革開放的時候的人能那麼容易賺錢,而輪到我們的時候,什麼事情都要正規化了?有一天我突然想,我還在上學的時候他們就在社會裏掙扎奮鬥了,他們在社會上奮鬥積累了十幾二十年,我們新人來了,他們有的我都想要,我這不是在要公平,我這是在要搶劫。因為我要得太急,因為我忍不住寂寞。二十多歲的男人,沒有錢,沒有事業,卻有蓬勃的欲望。
人總是會遇到挫折的,人總是會有低潮的,人總是會有不被人理解的時候的,人總是有要低聲下氣的時候,這些時候恰恰是人生最關鍵的時候,因為大家都會碰到挫折,而大多數人過不了這個門檻,你能過,你就成功了。在這樣的時刻,我們需要耐心等待,滿懷信心地去等待,相信,生活不會放棄你,機會總會來的。至少,你還年輕,你沒有坐牢,沒有生治不了的病,沒有欠還不起的債。比你不幸的人遠遠多過比你幸運的人,你還怕什麼?路要一步步走,雖然到達終點的那一步很激動人心,但大部分的腳步是平凡甚至枯燥的,但沒有這些腳步,或者耐不住這些平凡枯燥,你終歸是無法迎來最後的那些激動人心。
逆境,是上帝幫你淘汰競爭者的地方。要知道,你不好受,別人也不好受,你堅持不下去了,別人也一樣,千萬不要告訴別人你堅持不住了,那只能讓別人獲得堅持的信心,讓競爭者看著你微笑的面孔,失去信心,退出比賽。勝利屬於那些有耐心的人。
在最絕望的時候,我會去看電影《The Pursuit of Happyness》《JerryMaguire》,讓自己重新鼓起勇氣,因為,無論什麼時候,我們總還是有希望。當所有的人離開的時候,我不失去希望,我不放棄。每天下班坐在車裏,我喜歡哼著《隱形的翅膀》看著窗外,我知道,我在靜靜等待,等待屬於我的那一刻。
原貼裏伊吉網友的話我很喜歡,抄錄在這裏:
每個人都希望,自己是獨一無二的特殊者
含著金匙出生、投胎到好家庭、工作安排到電力局拿1w月薪這樣的小概率事件,當然最好輪到自己
紅軍長征兩萬五、打成右派反革命、胼手胝足犧牲尊嚴去奮鬥,最好留給祖輩父輩和別人
自然,不是每個吃過苦的人都會得到回報。但是,任何時代,每一個既得利益者身後,都有他的祖輩父輩奮鬥掙扎乃至流血付出生命的身影,羡慕別人有個好爸爸,沒什麼不可以,問題是,你的下一代,會有一個好爸爸嗎?
至於問到為什麼不能有同樣的贏面概率?我只能問:為什麼物種競爭中,人和猴子不能有同樣的贏面概率? 物競天擇。猴子的靈魂不一定比你卑微,但你身後有幾十萬年的類人猿進化積澱。
七、入對行 跟對人
在中國,大概很少有人是一份職業做到底的,雖然如此,第一份工作還是有些需要注意的地方,有兩件事情格外重要,第一件是”入行”,第二件事情是”跟人”。第一份工作對人最大的影響就是入行,現代的職業分工已經很細,我們基本上只能在一個行業裏成為專家,不可能在多個行業裏成為專家。很多案例也證明即使一個人在一個行業非常成功,到另外一個行業,往往完全不是那麼回事情,“你想改變世界,還是想賣一輩子汽水?”是賈伯斯邀請百事可樂總裁約翰•斯考利加盟蘋果時所說的話,結果這位在百事非常成功的約翰,到了蘋果表現平平。其實沒有哪個行業特別好,也沒有哪個行業特別差,或許有報導說哪個行業的平均薪資比較高,但是他們沒說的是,那個行業的平均壓力也比較大。看上去很美的行業一旦進入才發現很多地方其實並不那麼完美,只是外人看不見。
說實話,我自己都沒有發大財,所以我的建議只是讓人快樂工作的建議,不是如何發大財的建議,我們只討論一般普通打工者的情況。我認為選擇什麼行業並沒有太大關係,看問題不能只看眼前。比如,從前年開始,國家開始整頓醫療行業,很多醫藥公司開不下去,很多醫藥行業的銷售開始轉行。其實醫藥行業的不景氣是針對所有公司的,並非針對一家公司,大家的日子都不好過,這個時候跑掉是非常不划算的,大多數正規的醫藥公司即使不做新生意撐個兩三年總是能撐的,大多數醫藥銷售靠工資撐個兩三年也是可以撐的,國家不可能永遠捏著醫藥行業不放的,兩三年以後光景總歸還會好起來的,那個時候別人都跑了而你沒跑,那時的日子應該會好過很多。有的時候覺得自己這個行業不行了,問題是,再不行的行業,做得人少了也變成了好行業,當大家都覺得不好的時候,往往卻是最好的時候。大家都覺得金融行業好,金融行業門檻高不說,有多少人削尖腦袋要鑽進去,競爭激烈,進去以後還要時時提防,一個疏忽,就被後來的人給擠掉了,壓力巨大,又如何談得上快樂?也就未必是“好”工作了。
太陽能這個東西至今還不能進入實際應用的階段,但是中國已經有7家和太陽能有關的公司在紐交所上市了,國美、蘇寧永樂其實是貿易型企業,也能上市,魯泰紡織連續10年利潤增長超過50%,賣茶的一茶一座,賣衣服的海瀾之家都能上市……其實選什麼行業真的不重要,關鍵是怎麼做。事情都是人做出來的,關鍵是人。
有一點是需要記住的,這個世界上,有史以來直到我們能夠預見得到的未來,成功的人總是少數,有錢的人總是少數,大多數人是一般的,普通的,不太成功的。因此,大多數人的做法和看法,往往都不是距離成功最近的做法和看法。因此大多數人說好的東西不見得好,大多數人說不好的東西不見得不好。大多數人都去炒股的時候說明跌只是時間問題,大家越是熱情高漲的時候,跌的日子越近。大多數人買房子的時候,房價不會漲,而房價漲的差不多的時候,大多數人才開始買房子。不會有這樣一件事情讓大家都變成功,發了財,歷史上不曾有過,將來也不會發生。有些東西即使一時運氣好得到了,還是會在別的時候別的地方失去的。
年輕人在職業生涯的剛開始,尤其要注意的是,要做對的事情,不要讓自己今後幾十年的人生總是提心吊膽,更不值得為了一份工作賠上自己的青春年華。我的公司是個不行賄的公司,以前很多人不理解,甚至自己的員工也不理解,不過如今,我們是同行中最大的企業,客戶樂意和我們打交道,尤其是在國家打擊腐敗的時候,每個人都知道我們做生意不給錢的名聲,都敢於和我們做生意。而勇於給錢的公司,不是倒了,就是跑了,要不就是每天睡不好覺,人還是要看長遠一點。很多時候,看起來最近的路,其實是最遠的路,看起來最遠的路,其實是最近的路。
跟對人是說,入行後要跟個好領導好老師,剛進社會的人做事情往往沒有經驗,需要有人言傳身教。對於一個人的發展來說,一個好領導是非常重要的。所謂“好”的標準,不是他讓你少幹活多拿錢,而是以下三個。
首先,好領導要有寬廣的心胸,如果一個領導每天都會發脾氣,那幾乎可以肯定他不是個心胸寬廣的人,能發脾氣的時候卻不發脾氣的領導,多半是非常厲害的領導。中國人當領導最大的毛病是容忍不了能力比自己強的人,所以常常可以看到的一個現象是,領導很有能力,手下一群庸才或者手下一群閒人。如果看到這樣的環境,還是不要去的好。
其次,領導要願意從下屬的角度來思考問題,這一點其實是從面試的時候就能發現的,如果這位領導總是從自己的角度來考慮問題,幾乎不聽你說什麼,這就危險了。從下屬的角度來考慮問題並不代表同意下屬的說法,但他必須瞭解下屬的立場,下屬為什麼要這麼想,然後他才有辦法說服你,只關心自己怎麼想的領導往往難以獲得下屬的信服。
第三,領導敢於承擔責任,如果出了問題就把責任往下推,有了功勞就往自己身上攬,這樣的領導不跟也罷。選擇領導,要選擇關鍵時刻能抗得住的領導,能夠為下屬的錯誤買單的領導,因為這是他作為領導的責任。
有可能,你碰不到好領導,因為,中國的領導往往是屁股決定腦袋的領導,因為他坐領導的位置,所以他的話就比較有道理,這是傳統觀念官本位的誤區,可能有大量的這種無知無能的領導,只是,這對於你其實是好事,如果將來有一天你要超過他,你希望他比較聰明還是比較笨?相對來說這樣的領導其實不難搞定,只是你要把自己的身段放下來而已。多認識一些人,多和比自己強的人打交道,同樣能找到好的老師,不要和一群同樣鬱悶的人一起控訴社會,控訴老闆,這幫不上你,只會讓你更消極。和那些比你強的人打交道,看他們是怎麼想的,怎麼做的,學習他們,然後跟更強的人打交道。
八、選擇
我們每天做的最多的事情,其實是選擇,因此在談職業生涯的時候不得不提到這個話題。
我始終認為,在很大的範圍內,我們究竟會成為一個什麼樣的人,決定權在我們自己,每天我們都在做各種各樣的選擇,我可以不去寫這篇文章,去別人的帖子拍拍磚頭,也可以寫下這些文字,幫助別人的同時也整理自己的思路,我可以多注意下格式讓別人易於閱讀,也可以寫成一堆,我可以就這樣發上來,也可以在發以前再看幾遍,你可以選擇不刮鬍子就去面試,也可以選擇出門前照照鏡子……每天,每一刻我們都在做這樣那樣的決定,我們可以漫不經心,也可以多花些心思,成千上萬的小選擇累計起來,就決定了最終我們是個什麼樣的人。
從某種意義上來說我們的未來不是別人給的,是我們自己選擇的,很多人會說我命苦啊,沒得選擇阿,如果你認為“去微軟還是去IBM”“上清華還是上北大”“當銷售副總還是當廠長”這種才叫選擇的話,的確你沒有什麼選擇,大多數人都沒有什麼選擇。
一、關於工作與生活
我有個有趣的觀察,外企公司多的是25-35歲的白領,40歲以上的員工很少,二三十歲的外企員工是意氣風發的,但外企公司40歲附近的經理人是很尷尬的。我見過的40歲附近的外企經理人大多在一直跳槽,最後大多跳到民企,比方說,唐駿。外企員工的成功很大程度上是公司的成功,並非個人的成功,西門子的確比國美大,但並不代表西門子中國經理比國美的老闆強,甚至可以說差得很遠。而進外企的人往往並不能很早理解這一點,把自己的成功90%歸功於自己的能力,實際上,外企公司隨便換個中國區總經理並不會給業績帶來什麼了不起的影響。好了問題來了,當這些經理人40多歲了,他們的薪資要求變得很高,而他們的才能其實又不是那麼出眾,作為外企公司的老闆,你會怎麼選擇?有的是只要不高薪水的,要出位的精明強幹精力沖沛的年輕人,有的是,為什麼還要用你?
從上面這個例子,其實可以看到我們的工作軌跡,二三十歲的時候,生活的壓力還比較小,身體還比較好,上面的父母身體還好,下面又沒有孩子,不用還房貸,也沒有孩子要上大學,當個外企小白領還是很光鮮的,掙得不多也夠花了。但是人終歸要結婚生子,終歸會老,到了40歲,父母老了,要看病要吃藥,要有人看護,自己要還房貸,要過基本體面的生活,要養小孩……那個時候需要掙多少錢才夠花才重要。所以,看待工作,眼光要放遠一點,一時的誰高誰低並不能說明什麼。
從這個角度上來說,我不太贊成過於關注第一份工作的薪水,更沒有必要攀比第一份工作的薪水,這在剛剛出校園的學生中間是很常見的。正常人大概要工作 35年,這好比是一場馬拉松比賽,和真正的馬拉松比賽不同的是,這次比賽沒有職業選手,每個人都只有一次機會。要知到,有很多人甚至堅持不到終點,大多數人最後是走到終點的,只有少數人是跑過終點的,因此在剛開始的時候,去搶領先的位置並沒有太大的意義。剛進社會的時候如果進500強公司,大概能拿到3k -6k/月的工資,有些特別技術的人才可能可以到8k/月,可問題是,5年以後拿多少?估計5k-10k了不起了。起點雖然高,但增幅有限,而且,後面的年輕人追趕的壓力越來越大。
我前兩天問我的一個銷售,你會的這些東西一個新人2年就都學會了,但新人所要求的薪水卻只是你的一半,到時候,你怎麼辦?
職業生涯就像一場體育比賽,有初賽、復賽、決賽。初賽的時候大家都剛剛進社會,大多數都是實力一般的人,這時候努力一點認真一點很快就能讓人脫穎而出,於是有的人二十多歲做了經理,有的人遲些也終於贏得了初賽,三十多歲成了經理。然後是復賽,能參加復賽的都是贏得初賽的,每個人都有些能耐,在聰明才智上都不成問題,這個時候再想要勝出就不那麼容易了,單靠一點點努力和認真還不夠,要有很強的堅忍精神,要懂得靠團隊的力量,要懂得收服人心,要有長遠的眼光……
看上去贏得復賽並不容易,但,還不是那麼難。因為這個世界的規律就是給人一點成功的同時、讓人驕傲自滿,剛剛贏得初賽的人往往不知道自己贏得的僅僅是初賽,有了一點小小的成績大多數人都會驕傲自滿起來,認為自己已經懂得了全部,不需要再努力再學習了,他們會認為之所以不能再進一步已經不是自己的原因了。雖然他們仍然不好對付,但是他們沒有耐性,沒有容人的度量,更沒有清晰長遠的目光。就像一隻憤怒的鬥牛,雖然猛烈,最終是會敗的,而贏得復賽的人則象鬥牛士一樣,不急不躁,跟隨著自己的節拍,慢慢耗盡對手的耐心和體力。贏得了復賽以後,大約已經是一位很了不起的職業經理人了,當上了中小公司的總經理,大公司的副總經理,主管著每年幾千萬乃至幾億的生意。
最終的決賽來了,說實話我自己都還沒有贏得決賽,因此對於決賽的決勝因素也只能憑自己的猜測而已,這個時候的輸贏或許就像武俠小說裏寫得那樣,大家都是高手,只能等待對方犯錯了,要想輕易擊敗對手是不可能的,除了使上渾身解數,還需要一點運氣和時間。世界的規律依然發揮著作用,贏得復賽的人已經不只是驕傲自滿了,他們往往剛愎自用,聽不進去別人的話,有些人的脾氣變得暴躁,心情變得浮躁,身體變得糟糕,他們最大的敵人就是他們自己,在決賽中要做的只是不被自己擊敗,等著別人被自己擊敗。這和體育比賽是一樣的,最後高手之間的比賽,就看誰失誤少誰就贏得了決賽。
二、 根源
你工作快樂嗎?你的工作好嗎?
有沒有覺得幹了一段時間以後工作很不開心?有沒有覺得自己入錯了行?有沒有覺得自己沒有得到應有的待遇?有沒有覺得工作像一團亂麻每天上班都是一種痛苦?有沒有很想換個工作?有沒有覺得其實現在的公司並沒有當初想像得那麼好?有沒有覺得這份工作是當初因為生存壓力而找的,實在不適合自己?你從工作中得到你想要得到的了麼?你每天開心麼?
天涯上憤怒的人很多,你有沒有想過,你為什麼不快樂?你為什麼憤怒?
其實,你不快樂的根源,是因為你不知道要什麼!你不知道要什麼,所以你不知道去追求什麼,你不知道追求什麼,所以你什麼也得不到。
我總覺得,職業生涯首先要關注的是自己,自己想要什麼?大多數人大概沒想過這個問題,唯一的想法只是——我想要一份工作,我想要一份不錯的薪水,我知道所有人對於薪水的渴望,可是,你想每隔幾年重來一次找工作的過程麼?你想每年都在這種對於工作和薪水的焦急不安中度過麼?不想的話,就好好想清楚。飲鴆止渴,不能因為口渴就拼命喝毒藥。越是焦急,越是覺得自己需要一份工作,越饑不擇食,越想不清楚,越容易失敗,你的經歷越來越差,下一份工作的人看著你的簡歷就皺眉頭。於是你越喝越渴,越渴越喝,陷入惡性循環。最終只能哀歎世事不公或者生不逢時,只能到天涯上來發洩一把,在失敗者的共鳴當中尋求一點心理平衡罷了。大多數人都有生存壓力,我也是,有生存壓力就會有很多焦慮,積極的人會從焦慮中得到動力,而消極的人則會因為焦慮而迷失方向。所有人都必須在壓力下做出選擇,這就是世道,你喜歡也罷不喜歡也罷。
一般我們處理的事情分為重要的事情和緊急的事情,如果不做重要的事情就會常常去做緊急的事情。比如鍛煉身體保持健康是重要的事情,而看病則是緊急的事情。如果不鍛煉身體保持健康,就會常常為了病痛煩惱。又比如防火是重要的事情,而救火是緊急的事情,如果不注意防火,就要常常救火。找工作也是如此,想好自己究竟要什麼是重要的事情,找工作是緊急的事情,如果不想好,就會常常要找工作。往往緊急的事情給人的壓力比較大,迫使人們去趕緊做,相對來說重要的事情反而沒有那麼大的壓力,大多數人做事情都是以壓力為導向的,壓力之下,總覺得非要先做緊急的事情,結果就是永遠到處救火,永遠沒有停歇的時候。(很多人的工作也像是救火隊一樣忙碌痛苦,也是因為工作中沒有做好重要的事情。)那些說自己活在水深火熱為了生存顧不上那麼多的朋友,今天找工作困難是當初你們沒有做重要的事情,是結果不是原因。如果今天你們還是因為急於要找一份工作而不去思考,那麼或許將來要繼續承受痛苦找工作的結果。
我始終覺得我要說的話題,沉重了點,需要很多思考,遠比唐笑打武警的話題來的枯燥乏味,但是,天下沒有輕鬆的成功,成功,要付代價。請先忘記一切的生存壓力,想想這輩子你最想要的是什麼?所以,最要緊的事情,先想好自己想要什麼。
三、什麼是好工作
當初微軟有個唐駿,很多大學裏的年輕人覺得這才是他們嚮往的職業生涯,我在清華bbs裏發的帖子被這些學子們所不屑,那個時候學生們只想出國或者去外企,不過如今看來,我還是對的,唐駿去了盛大,陳天橋創立的盛大,一家民營公司。一個高學歷的海歸在500強的公司裏拿高薪水,這大約是很多年輕人的夢想,問題是,每年畢業的大學生都在做這個夢,好的職位卻只有500個。
人都是要面子的,也是喜歡攀比的,即使在工作上也喜歡攀比,不管那是不是自己想要的。大家認為外企公司很好,可是好在哪里呢?好吧,他們在比較好的寫字樓,這是你想要的麼?他們出差住比較好的酒店,這是你想要的麼?別人會羡慕一份外企公司的工作,這是你想要的麼?那一切都是給別人看的,你幹嗎要活得那麼辛苦給別人看?另一方面,他們薪水福利一般,並沒有特別了不起,他們的晉升機會比較少,很難做到很高階的主管,他們雖然厭惡常常加班,卻不敢不加班,因為“你不幹有得是人幹”,大部分情況下會找個臺灣人香港人新加坡人來管你,而這些人又往往有些莫名其妙的優越感。你想清楚了麼?500強一定好麼?找工作究竟是考慮你想要什麼,還是考慮別人想看什麼?
我的大學同學們大多數都到美國了,甚至畢業這麼多年了,還有人最近到國外去了。出國真的有那麼好麼?我的大學同學們,大多數還是在博士、博士後、訪問學者地掙扎著,至今只有一個正經在一個美國大學裏拿到個正式的教職。國內的教授很難當麼?我有幾個表親也去了國外了,他們的父母獨自在國內,沒有人照顧,有好幾次人在家裏昏倒都沒人知道,出國,真的這麼光彩麼?就像有人說的“很多事情就像看A片,看的人覺得很爽,做的人未必。”
人總想找到那個最好的,可是,什麼是最好的?你覺得是最好的那個,是因為你的確瞭解,還是因為別人說他是最好的?即使他對於別人是最好的,對於你也一定是最好的麼?
對於自己想要什麼,自己要最清楚,別人的意見並不是那麼重要。很多人總是常常被別人的意見所影響,親戚的意見,朋友的意見,同事的意見……問題是,你究竟是要過誰的一生?人的一生不是父母一生的續集,也不是兒女一生的前傳,更不是朋友一生的外篇,只有你自己對自己的一生負責,別人無法也負不起這個責任。自己做的決定,至少到最後,自己沒什麼可後悔。對於大多數正常智力的人來說,所做的決定沒有大的對錯,無論怎麼樣的選擇,都是可以嘗試的。比如你沒有考自己上的那個學校,沒有入現在這個行業,這輩子就過不下去了?就會很失敗?不見得。
我想,好工作,應該是適合你的工作,具體點說,應該是能給你帶來你想要的東西的工作,你或許應該以此來衡量你的工作究竟好不好,而不是拿公司的大小,規模,外企還是國企,是不是有名,是不是上市公司來衡量。小公司,未必不是好公司,賺錢多的工作,也未必是好工作。你還是要先弄清楚你想要什麼,如果你不清楚你想要什麼,你就永遠也不會找到好工作,因為你永遠只看到你得不到的東西,你得到的,都是你不想要的。
可能,最好的,已經在你的身邊,只是,你還沒有學會珍惜。人們總是盯著得不到的東西,而忽視了那些已經得到的東西。
四、普通人
我發現中國人的勵志和國外的勵志存在非常大的不同,中國的勵志比較鼓勵人立下大志願,臥薪嚐膽,有朝一日成富成貴。而國外的勵志比較鼓勵人勇敢面對現實生活,面對普通人的困境,雖然結果也是成富成貴,但起點不一樣,相對來說,我覺得後者在操作上更現實,而前者則需要用999個失敗者來堆砌一個成功者的故事。
我們都是普通人,普通人的意思就是,概率這件事是很準的。因此,我們不會買彩票中500萬,我們不會成為比爾蓋茨或者李嘉誠,我們不會坐飛機掉下來,我們當中很少的人會創業成功,我們之中有30%的人會離婚,我們之中大部分人會活過65歲……
所以請你在想自己要什麼的時候,要得“現實”一點,你說我想要做李嘉誠,抱歉,我幫不上你。成為比爾蓋茨或者李嘉誠這種人,是靠命的,看我寫的這篇文章絕對不會讓你成為他們,即使你成為了他們,也絕對不是我這篇文章的功勞。“王侯將相甯有種乎”但真正當皇帝的只有一個人,王侯將相,人也不多。目標定得高些對於喜歡挑戰的人來說有好處,但對於大多數普通人來說,反而比較容易灰心沮喪,很容易就放棄了。
回過頭來說,李嘉誠比你有錢大致50萬倍,他比你更快樂麼?或許。有沒有比你快樂50萬倍,一定沒有。他比你最多也就快樂一兩倍,甚至有可能還不如你快樂。尋找自己想要的東西不是和別人比賽,比誰要得更多更高,比誰的目標更遠大。雖然成為李嘉誠這個目標很宏大,但你並不見得會從這個目標以及追求目標的過程當中獲得快樂,而且基本上你也做不到。你必須聽聽你內心的聲音,尋找真正能夠使你獲得快樂的東西,那才是你想要的東西。
你想要的東西,或者我們把它稱之為目標,目標其實並沒有高低之分,你不需要因為自己的目標沒有別人遠大而不好意思,達到自己的目標其實就是成功,成功有大有小,快樂卻是一樣的。我們追逐成功,其實追逐的是成功帶來的快樂,而非成功本身。職業生涯的道路上,我們常常會被攀比的心態蒙住眼睛,忘記了追求的究竟是什麼,忘記了是什麼能使我們更快樂。
社會上一夜暴富的新聞很多,這些消息,總會在我們的心裏面掀起很多漣漪,漣漪多了就變成驚濤駭浪,心裏的驚濤駭浪除了打翻承載你目標的小船,並不會使得你也一夜暴富。“只見賊吃肉,不見賊挨揍。”我們這些普通人既沒有當賊的勇氣,又缺乏當賊的狠辣絕決,雖然羡慕吃肉,卻更害怕挨揍,偶爾看到幾個沒挨揍的賊就按奈不住,或者心思活動,或者大感不公,真要叫去做賊,卻也不敢。
我還是過普通人的日子,要普通人的快樂,至少,晚上睡得著覺。
五、跳槽與積累
首先要說明,工作是一件需要理智的事情,所以不要在工作上耍個性,天涯上或許會有人覺得你很有個性而叫好,煤氣公司電話公司不會因為覺得你很有個性而免了你的帳單。當你很帥地炒掉了你的老闆,當你很酷地挖苦了一番招聘的HR,帳單還是要照付,只是你賺錢的時間更少了,除了你自己,沒人受損失。
我並不反對跳槽,但跳槽決不是解決問題的辦法,而且頻繁跳槽的後果是讓人覺得沒有忠誠度可言,而且不能安心工作。現在很多人從網上找工作,很多找工作的網站常常給人出些餿主意,要知道他們是盈利性企業,當然要從自身盈利的角度來考慮,大家越是頻繁跳槽頻繁找工作他們越是生意興隆,所以鼓動人們跳槽是他們的工作。所以他們會常常告訴你,你拿的薪水少了,你享受的福利待遇差了,又是“薪情快報”又是“讚歎自由奔放的靈魂”。至於是否會因此讓你不能安心,你跳了槽是否解決問題,是否更加開心,那個,他們管不著。
要跳槽肯定是有問題,一般來說問題發生了,躲是躲不開的,很多人跳槽是因為這樣或者那樣的不開心,如果這種不開心,在現在這個公司不能解決,那麼在下一個公司多半也解決不掉。你必須相信,90%的情況下,你所在的公司並沒有那麼爛,你認為不錯的公司也沒有那麼好。就像圍城裏說的,“城裏的人拼命想衝出來,而城外的人拼命想衝進去。”每個公司都有每個公司的問題,沒有問題的公司是不存在的。換個環境你都不知道會碰到什麼問題,與其如此,不如就在當下把問題解決掉。很多問題當你真的想要去解決的時候,或許並沒有那麼難。有的時候你覺得問題無法解決,事實上,那只是“你覺得”。
人生的曲線應該是曲折向上的,偶爾會遇到低谷但大趨勢總歸是曲折向上的,而不是象脈衝波一樣每每回到起點,我見過不少面試者,30多歲了,四五份工作經歷,每次多則3年,少則1年,30多歲的時候回到起點從一個初級職位開始幹起,拿基本初級的薪水,和20多歲的年輕人一起競爭,不覺得有點辛苦麼?這種日子好過麼?
我非常不贊成在一個行業超過3年以後換行業,基本上,35歲以前我們的生存資本靠打拼,35歲以生存的資本靠的就是積累,這種積累包括人際關係,經驗,人脈,口碑……如果常常更換行業,代表幾年的積累付之東流,一切從頭開始,如果換了兩次行業,35歲的時候大概只有5年以下的積累,而一個沒有換過行業的人至少有了10年的積累,誰會佔優勢?工作到2-3年的時候,很多人覺得工作不順利,好像到了一個瓶頸,心情煩悶,就想辭職,乃至換一個行業,覺得這樣所有一切煩惱都可以拋開,會好很多。其實這樣做只是讓你從頭開始,到了時候還是會發生和原來行業一樣的困難,熬過去就向上跨了一大步,要知道每個人都會經歷這個過程,每個人的職業生涯中都會碰到幾個瓶頸,你熬過去了而別人沒有熬過去你就領先了。跑長跑的人會知道,開始的時候很輕鬆,但是很快會有第一次的難受,但過了這一段又能跑很長一段,接下來會碰到第二次的難受,堅持過了以後又能跑一段,如此往復,難受一次比一次厲害,直到堅持不下去了。大多數人第一次就堅持不了了,一些人能堅持到第二次,第三次雖然大家都堅持不住了,可是跑到這裏的人也沒幾個了,這點資本足夠你安穩活這一輩子了。
一份工作到兩三年的時候,大部分人都會變成熟手,這個時候往往會陷入不斷的重複,有很多人會覺得厭倦,有些人會覺得自己已經搞懂了一切,從而懶得去尋求進步了。很多時候的跳槽是因為覺得失去興趣了,覺得自己已經完成比賽了。其實這個時候比賽才剛剛開始,工作兩三年的人,無論是客戶關係,人脈,手下,和領導的關係,在業內的名氣……還都是遠遠不夠的,但稍有成績的人總是會自我感覺良好的,每個人都覺得自己跟客戶關係鐵得要命,覺得自己在業界的口碑好得很。其實可以肯定地說,一定不是,這個時候,還是要拿出前兩年的幹勁來,穩紮穩打,積累才剛剛開始。
你足夠瞭解你的客戶嗎?你知道他最大的煩惱是什麼嗎?你足夠瞭解你的老闆麼?你知道他最大的煩惱是什麼嗎?你足夠瞭解你的手下麼?你知道他最大的煩惱是什麼嗎?如果你不知道,你憑什麼覺得自己已經積累夠了?如果你都不瞭解,你怎麼能讓他們幫你的忙,做你想讓他們做的事情?如果他們不做你想讓他們做的事情,你又何來的成功?
六、等待
這是個浮躁的人們最不喜歡的話題,本來不想說這個話題,因為會引起太多的爭論,而我又無意和人爭論這些,但是考慮到對於職業生涯的長久規劃,這是一個躲避不了的話題,還是決定寫一寫,不愛看的請離開吧。
並不是每次穿紅燈都會被汽車撞,並不是每個罪犯都會被抓到,並不是每個錯誤都會被懲罰,並不是每個貪官都會被槍斃,並不是你的每一份努力都會得到回報,並不是你的每一次堅持都會有人看到,並不是你每一點付出都能得到公正的回報,並不是你的每一個善意都能被理解……這個,就是世道。好吧,世道不夠好,可是,你有推翻世道的勇氣麼?如果沒有,你有更好的解決辦法麼?有很多時候,人需要一點耐心,一點信心。每個人總會輪到幾次不公平的事情,而通常,安心等待是最好的辦法。
有很多時候我們需要等待,需要耐得住寂寞,等待屬於你的那一刻。周潤發等待過,劉德華等待過,周星馳等待過,王菲等待過,張藝謀也等待過……看到了他們如今的功成名就的人,你可曾看到當初他們的等待和耐心?你可曾看到金馬獎影帝在街邊擺地攤?你可曾看到德雲社一群人在劇場裏給一位觀眾說相聲?你可曾看到周星馳的角色甚至連一句臺詞都沒有?每一個成功者都有一段低沉苦悶的日子,我幾乎能想像得出來他們借酒澆愁的樣子,我也能想像得出他們為了生存而掙扎的窘迫。在他們一生最中燦爛美好的日子裏,他們渴望成功,但卻兩手空空,一如現在的你。沒有人保證他們將來一定會成功,而他們的選擇是耐住寂寞。如果當時的他們總念叨著“成功只是屬於特權階級的”,你覺得他們今天會怎樣?
曾經我也不明白有些人為什麼並不比我有能力卻要坐在我的頭上,年紀比我大就一定要當我的領導麼?為什麼有些爛人不需要努力就能賺錢?為什麼剛剛改革開放的時候的人能那麼容易賺錢,而輪到我們的時候,什麼事情都要正規化了?有一天我突然想,我還在上學的時候他們就在社會裏掙扎奮鬥了,他們在社會上奮鬥積累了十幾二十年,我們新人來了,他們有的我都想要,我這不是在要公平,我這是在要搶劫。因為我要得太急,因為我忍不住寂寞。二十多歲的男人,沒有錢,沒有事業,卻有蓬勃的欲望。
人總是會遇到挫折的,人總是會有低潮的,人總是會有不被人理解的時候的,人總是有要低聲下氣的時候,這些時候恰恰是人生最關鍵的時候,因為大家都會碰到挫折,而大多數人過不了這個門檻,你能過,你就成功了。在這樣的時刻,我們需要耐心等待,滿懷信心地去等待,相信,生活不會放棄你,機會總會來的。至少,你還年輕,你沒有坐牢,沒有生治不了的病,沒有欠還不起的債。比你不幸的人遠遠多過比你幸運的人,你還怕什麼?路要一步步走,雖然到達終點的那一步很激動人心,但大部分的腳步是平凡甚至枯燥的,但沒有這些腳步,或者耐不住這些平凡枯燥,你終歸是無法迎來最後的那些激動人心。
逆境,是上帝幫你淘汰競爭者的地方。要知道,你不好受,別人也不好受,你堅持不下去了,別人也一樣,千萬不要告訴別人你堅持不住了,那只能讓別人獲得堅持的信心,讓競爭者看著你微笑的面孔,失去信心,退出比賽。勝利屬於那些有耐心的人。
在最絕望的時候,我會去看電影《The Pursuit of Happyness》《JerryMaguire》,讓自己重新鼓起勇氣,因為,無論什麼時候,我們總還是有希望。當所有的人離開的時候,我不失去希望,我不放棄。每天下班坐在車裏,我喜歡哼著《隱形的翅膀》看著窗外,我知道,我在靜靜等待,等待屬於我的那一刻。
原貼裏伊吉網友的話我很喜歡,抄錄在這裏:
每個人都希望,自己是獨一無二的特殊者
含著金匙出生、投胎到好家庭、工作安排到電力局拿1w月薪這樣的小概率事件,當然最好輪到自己
紅軍長征兩萬五、打成右派反革命、胼手胝足犧牲尊嚴去奮鬥,最好留給祖輩父輩和別人
自然,不是每個吃過苦的人都會得到回報。但是,任何時代,每一個既得利益者身後,都有他的祖輩父輩奮鬥掙扎乃至流血付出生命的身影,羡慕別人有個好爸爸,沒什麼不可以,問題是,你的下一代,會有一個好爸爸嗎?
至於問到為什麼不能有同樣的贏面概率?我只能問:為什麼物種競爭中,人和猴子不能有同樣的贏面概率? 物競天擇。猴子的靈魂不一定比你卑微,但你身後有幾十萬年的類人猿進化積澱。
七、入對行 跟對人
在中國,大概很少有人是一份職業做到底的,雖然如此,第一份工作還是有些需要注意的地方,有兩件事情格外重要,第一件是”入行”,第二件事情是”跟人”。第一份工作對人最大的影響就是入行,現代的職業分工已經很細,我們基本上只能在一個行業裏成為專家,不可能在多個行業裏成為專家。很多案例也證明即使一個人在一個行業非常成功,到另外一個行業,往往完全不是那麼回事情,“你想改變世界,還是想賣一輩子汽水?”是賈伯斯邀請百事可樂總裁約翰•斯考利加盟蘋果時所說的話,結果這位在百事非常成功的約翰,到了蘋果表現平平。其實沒有哪個行業特別好,也沒有哪個行業特別差,或許有報導說哪個行業的平均薪資比較高,但是他們沒說的是,那個行業的平均壓力也比較大。看上去很美的行業一旦進入才發現很多地方其實並不那麼完美,只是外人看不見。
說實話,我自己都沒有發大財,所以我的建議只是讓人快樂工作的建議,不是如何發大財的建議,我們只討論一般普通打工者的情況。我認為選擇什麼行業並沒有太大關係,看問題不能只看眼前。比如,從前年開始,國家開始整頓醫療行業,很多醫藥公司開不下去,很多醫藥行業的銷售開始轉行。其實醫藥行業的不景氣是針對所有公司的,並非針對一家公司,大家的日子都不好過,這個時候跑掉是非常不划算的,大多數正規的醫藥公司即使不做新生意撐個兩三年總是能撐的,大多數醫藥銷售靠工資撐個兩三年也是可以撐的,國家不可能永遠捏著醫藥行業不放的,兩三年以後光景總歸還會好起來的,那個時候別人都跑了而你沒跑,那時的日子應該會好過很多。有的時候覺得自己這個行業不行了,問題是,再不行的行業,做得人少了也變成了好行業,當大家都覺得不好的時候,往往卻是最好的時候。大家都覺得金融行業好,金融行業門檻高不說,有多少人削尖腦袋要鑽進去,競爭激烈,進去以後還要時時提防,一個疏忽,就被後來的人給擠掉了,壓力巨大,又如何談得上快樂?也就未必是“好”工作了。
太陽能這個東西至今還不能進入實際應用的階段,但是中國已經有7家和太陽能有關的公司在紐交所上市了,國美、蘇寧永樂其實是貿易型企業,也能上市,魯泰紡織連續10年利潤增長超過50%,賣茶的一茶一座,賣衣服的海瀾之家都能上市……其實選什麼行業真的不重要,關鍵是怎麼做。事情都是人做出來的,關鍵是人。
有一點是需要記住的,這個世界上,有史以來直到我們能夠預見得到的未來,成功的人總是少數,有錢的人總是少數,大多數人是一般的,普通的,不太成功的。因此,大多數人的做法和看法,往往都不是距離成功最近的做法和看法。因此大多數人說好的東西不見得好,大多數人說不好的東西不見得不好。大多數人都去炒股的時候說明跌只是時間問題,大家越是熱情高漲的時候,跌的日子越近。大多數人買房子的時候,房價不會漲,而房價漲的差不多的時候,大多數人才開始買房子。不會有這樣一件事情讓大家都變成功,發了財,歷史上不曾有過,將來也不會發生。有些東西即使一時運氣好得到了,還是會在別的時候別的地方失去的。
年輕人在職業生涯的剛開始,尤其要注意的是,要做對的事情,不要讓自己今後幾十年的人生總是提心吊膽,更不值得為了一份工作賠上自己的青春年華。我的公司是個不行賄的公司,以前很多人不理解,甚至自己的員工也不理解,不過如今,我們是同行中最大的企業,客戶樂意和我們打交道,尤其是在國家打擊腐敗的時候,每個人都知道我們做生意不給錢的名聲,都敢於和我們做生意。而勇於給錢的公司,不是倒了,就是跑了,要不就是每天睡不好覺,人還是要看長遠一點。很多時候,看起來最近的路,其實是最遠的路,看起來最遠的路,其實是最近的路。
跟對人是說,入行後要跟個好領導好老師,剛進社會的人做事情往往沒有經驗,需要有人言傳身教。對於一個人的發展來說,一個好領導是非常重要的。所謂“好”的標準,不是他讓你少幹活多拿錢,而是以下三個。
首先,好領導要有寬廣的心胸,如果一個領導每天都會發脾氣,那幾乎可以肯定他不是個心胸寬廣的人,能發脾氣的時候卻不發脾氣的領導,多半是非常厲害的領導。中國人當領導最大的毛病是容忍不了能力比自己強的人,所以常常可以看到的一個現象是,領導很有能力,手下一群庸才或者手下一群閒人。如果看到這樣的環境,還是不要去的好。
其次,領導要願意從下屬的角度來思考問題,這一點其實是從面試的時候就能發現的,如果這位領導總是從自己的角度來考慮問題,幾乎不聽你說什麼,這就危險了。從下屬的角度來考慮問題並不代表同意下屬的說法,但他必須瞭解下屬的立場,下屬為什麼要這麼想,然後他才有辦法說服你,只關心自己怎麼想的領導往往難以獲得下屬的信服。
第三,領導敢於承擔責任,如果出了問題就把責任往下推,有了功勞就往自己身上攬,這樣的領導不跟也罷。選擇領導,要選擇關鍵時刻能抗得住的領導,能夠為下屬的錯誤買單的領導,因為這是他作為領導的責任。
有可能,你碰不到好領導,因為,中國的領導往往是屁股決定腦袋的領導,因為他坐領導的位置,所以他的話就比較有道理,這是傳統觀念官本位的誤區,可能有大量的這種無知無能的領導,只是,這對於你其實是好事,如果將來有一天你要超過他,你希望他比較聰明還是比較笨?相對來說這樣的領導其實不難搞定,只是你要把自己的身段放下來而已。多認識一些人,多和比自己強的人打交道,同樣能找到好的老師,不要和一群同樣鬱悶的人一起控訴社會,控訴老闆,這幫不上你,只會讓你更消極。和那些比你強的人打交道,看他們是怎麼想的,怎麼做的,學習他們,然後跟更強的人打交道。
八、選擇
我們每天做的最多的事情,其實是選擇,因此在談職業生涯的時候不得不提到這個話題。
我始終認為,在很大的範圍內,我們究竟會成為一個什麼樣的人,決定權在我們自己,每天我們都在做各種各樣的選擇,我可以不去寫這篇文章,去別人的帖子拍拍磚頭,也可以寫下這些文字,幫助別人的同時也整理自己的思路,我可以多注意下格式讓別人易於閱讀,也可以寫成一堆,我可以就這樣發上來,也可以在發以前再看幾遍,你可以選擇不刮鬍子就去面試,也可以選擇出門前照照鏡子……每天,每一刻我們都在做這樣那樣的決定,我們可以漫不經心,也可以多花些心思,成千上萬的小選擇累計起來,就決定了最終我們是個什麼樣的人。
從某種意義上來說我們的未來不是別人給的,是我們自己選擇的,很多人會說我命苦啊,沒得選擇阿,如果你認為“去微軟還是去IBM”“上清華還是上北大”“當銷售副總還是當廠長”這種才叫選擇的話,的確你沒有什麼選擇,大多數人都沒有什麼選擇。
讓Vista用administrator登入
以下步驟可以讓Vista用administrator登入....
1. 以管理員身份執行 cmd.exe
2. 輸入「net users Administrator /active:yes」
3. 執行「regedit」
4. 找到 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
5. 雙擊點選「FilterAdministratorToken」並將值修改至 「0」
6. 登出再登入
1. 以管理員身份執行 cmd.exe
2. 輸入「net users Administrator /active:yes」
3. 執行「regedit」
4. 找到 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
5. 雙擊點選「FilterAdministratorToken」並將值修改至 「0」
6. 登出再登入
2009年7月7日 星期二
SQL Server2005 匯入文字檔貨EXCEL檔發生錯誤
今天在用MSSQL 2005從txt匯入資料,發生了這個錯誤。
上網查了後,發現是Integration Services沒有灌的緣故,所以就把它給他又灌上去,相當快速的解決了這個問題,記錄下來已防日後老年癡呆XD
參考網站:錯誤 0xc00470fe XXX的產品層級不夠
錯誤 0xc00470fe : 資料流程工作 : 元件 來源 xxxxxxx 的產品層級不夠。
錯誤 0xc00470fe : 資料流程工作 : 元件 資料轉換 xxxxxxx 的產品層級不夠。
上網查了後,發現是Integration Services沒有灌的緣故,所以就把它給他又灌上去,相當快速的解決了這個問題,記錄下來已防日後老年癡呆XD
參考網站:錯誤 0xc00470fe XXX的產品層級不夠
訂閱:
文章 (Atom)