閱讀288 返回首頁    go 阿裏雲 go 技術社區[雲棲]


鬧鍾的設計原理與實現

鬧鍾的設計原理與實現(一)

 

華中科技大學 陳學友

2012年5月18日

 

 

內容摘要

現在很多人由於需要處理各種事物,但是由於某些原因可能會忘記在某個時間段需要完成的工作和其他事情,因此需要一個鬧鍾來提醒自己,避免忘記這些應該做的事情。如果隻有一個提醒事件,情況非常簡單,但是對於多事件提醒的鬧鍾來說,如何解決提醒不衝突,如何使資源占據最小是一個迫切需要解決的問題。本文介紹一個鬧鍾的設計與實現,此外還提出一種最近時間的方式來解決鬧鍾的設計問題。

 

關鍵詞

鬧鍾  最近時間 多時間提醒處理機製

 

 

論文內容

一、簡單的鬧鍾的設計原理

 

一個鬧鍾提醒包括三部分:

 

提醒的開始時間

重複周期

提醒的內容

 

提醒的開始時間是鬧鍾不可少的,提醒的內容是能夠有效的提醒用戶接下來要做的事情。很多鬧鍾是一次性鬧鍾,因此沒有重複的周期,比如某天去機場車站接人或者參加某個考試等。還有很多事件需要定期的重複提醒,比如朋友的生日通常一年一次,起床鬧鍾通常每天都有。如果不設計【重複周期】,用戶每次都得輸入一個新的鬧鍾,這將是一件非常繁瑣的事。我們希望盡量能有減少這種不友好的設計,因此【重複周期】是不可少的,在這種情況下,

【重複周期】=N

就代表是單次鬧鍾了。

【重複周期】可以是每年,每月,每周,每日,每時,每小時,每分,每秒(嗯,好吧,每秒都提醒這個意義可能不是很大,至少很少有人會有這種提醒的需要),也可以是用戶自定義的時間間隔,比如是6小時等。理論上重複的周期也可以是一個世紀或者一千年。

對於多時間提醒的鬧鍾,需要生成一個提醒的列表來保存需要提醒的時間。

 

提醒的開始時間

重複周期

提醒的內容

S1

T1

Text1

S2

T2

Text2

S3

T3

Text3

 

舉例說明一下,

設係統的時鍾為Tn,假設一個提醒時間為

2012/5/20 13:30:00

每天

該起床了

 

那麼我們需要提醒的時間就有

2012/5/2013:30:00

2012/5/2113:30:00

2012/5/2213:30:00

….

 

 

我們知道對於上麵的例子,可以有一個簡單的實現方法,那就是檢測

Tn.Hour==13&&Tn.Mintue=30&&Tn.second==00

條件是否成立,這樣我們就能實現每天都提醒該事件的發生。同樣對於每年,每月也采用類似的方式。再如生日提醒

1990/5/20 13:30:00

每年

生日快樂

 

可以表示為

If(Tn.Month==5&& Tn.Day==20&& Tn.Hour==13&&Tn.Mintue=30&&Tn.second==00)

{

    鬧鍾提醒;

}

 

但是對於一個【重複周期】為6小時的吃藥時間提醒,

2012/5/20 13:30:00

每5小時

吃藥

那麼我們需要提醒的時間就有

2012/5/2013:30:00

2012/5/2018:30:00

2012/5/2123:30:00

2012/5/2104:30:00

……

如果使用上麵的方法就無法準確提醒了。下一節介紹如何處理這個問題。

二、複雜的鬧鍾的設計原理

 

為解決上一節提出的自定義時間提醒問題,需要引入一個【真實提醒時間】。所謂【真實提醒時間】是指下一次要提醒時與係統進行比對,匹配則觸發提醒事件的鬧鍾時間。

對於

 

2012/5/20 13:30:00

每5小時

吃藥

 

這個提醒事件,假設當前係統時間Tn=2012/5/20 17:00:00. 那麼【真實提醒時間】隻有一個,且等於2012/5/2018:30:00.

與此對應,一個鬧鍾提醒除了原有的三部分外,還要增加【真實提醒時間】:

 

提醒的開始時間

重複周期

提醒的內容

真實提醒時間

 

【真實時間】可以根據係統的當前時間動態改變。下麵討論真實時間如何計算。

設S表示【提醒的開始時間】,Tv表示【真實提醒時間】,,Tc表示【重複周期】,則

 

Tv=S;

While(Tv<Tn)

Tv+=Tc;

最後,新的提醒事件列表就變成這樣

提醒的開始時間

重複周期

提醒的內容

真實提醒時間

S1

T1

Text1

Tv1

S2

T2

Text2

Tv2

S3

T3

Text3

Tv3

 

我們隻需要將Tn與Tvi一一比對就可以準確的觸發提醒事件了。觸發某個事件後將

Tvi+=Tci;

就可以得到下一次的真實提醒時間列表了。

 

進一步優化

既然擁有了Tv這張【真實提醒時間】,我們都知道,時間是線性的,因此Tvi與Tvj必然有一個大小關係,假設 Tvmin=Min{Tvi|i=1,2,3,….};那麼我們就不需要每次都遍曆這個【真實提醒時間】列表了。在初始化和列表發生改動是重新計算Tvmin,

If(Tn==Tvmin)

{

    提醒事件;

更新Tv列表;

Tvmin==Min{Tvi|i=1,2,3,….};

}


最後更新:2017-04-02 17:28:39

  上一篇:go Hibernate的在線API
  下一篇:go sql時間函數