caltest.f90 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. ! =============
  2. ! MODULE CALMOD
  3. ! =============
  4. module calmod
  5. implicit none
  6. integer :: mondays(0:12) = (/0,31,28,31,30,31,30,31,31,30,31,30,31/)
  7. integer :: monaccu(0:12)
  8. integer :: ny400d = 400 * 365 + 97
  9. integer :: ny100d = 100 * 365 + 24
  10. integer :: ny004d = 4 * 365 + 1
  11. integer :: ny001d = 365
  12. end module calmod
  13. ! =================
  14. ! FUNCTION NWEEKDAY
  15. ! =================
  16. integer function nweekday(kday)
  17. nweekday = mod(kday+6,7)
  18. return
  19. end
  20. ! ===================
  21. ! SUBROUTINE STEP2CAL
  22. ! ===================
  23. subroutine step2cal(kstep,ktspd,kyea,kmon,kday,khou,kmin)
  24. use calmod
  25. implicit none
  26. integer, intent(IN ) :: kstep ! time step since simulation start
  27. integer, intent(IN ) :: ktspd ! time steps per day
  28. integer, intent(OUT) :: kyea ! current year of simulation
  29. integer, intent(OUT) :: kmon ! current month of simulation
  30. integer, intent(OUT) :: kday ! current day of simulation
  31. integer, intent(OUT) :: khou ! current hour of simulation
  32. integer, intent(OUT) :: kmin ! current minute of simulation
  33. integer :: idall
  34. integer :: istp
  35. integer :: iy400,id400
  36. integer :: iy100,id100
  37. integer :: iy004,id004
  38. integer :: iy001,id001
  39. integer :: jmon
  40. logical :: leap
  41. idall = kstep / ktspd
  42. iy400 = idall / ny400d ! segment [of 400 years]
  43. id400 = mod(idall,ny400d)
  44. if (id400 <= ny100d) then ! century year is leap year
  45. iy100 = 0 ! century in segment [0]
  46. id100 = id400
  47. iy004 = id100 / ny004d ! tetrade in century [0..24]
  48. id004 = mod(id100 , ny004d)
  49. leap = (id004 <= ny001d)
  50. if (leap) then
  51. iy001 = 0 ! year in tetrade [0]
  52. id001 = id004
  53. else
  54. iy001 = (id004-1)/ny001d ! year in tetrade [1,2,3]
  55. id001 = mod(id004-1, ny001d)
  56. endif
  57. else ! century year is not leap year
  58. iy100 = (id400-1)/ny100d ! century in segment [1,2,3]
  59. id100 = mod(id400-1, ny100d)
  60. if (id100 < ny004d-1) then
  61. iy004 = 0 ! tetrade in century [0]
  62. id004 = id100
  63. leap = .false.
  64. iy001 = id004/ny001d ! year in tetrade [1,2,3]
  65. id001 = mod(id004,ny001d)
  66. else
  67. iy004 = (id100+1)/ny004d ! tetrade in century [1..24]
  68. id004 = mod(id100+1,ny004d)
  69. leap = (id004 <= ny001d)
  70. if (leap) then
  71. iy001 = 0 ! year in tetrade [0]
  72. id001 = id004
  73. else
  74. iy001 = (id004-1)/ny001d
  75. id001 = mod(id004-1, ny001d)
  76. endif
  77. endif
  78. endif
  79. kyea = iy400 * 400 + iy100 * 100 + iy004 * 4 + iy001
  80. ! print *,"yea ",kyea,iy400,iy100,iy004,iy001,id004,ny001d
  81. monaccu(0) = mondays(0)
  82. monaccu(1) = mondays(1)
  83. monaccu(2) = mondays(1) + mondays(2)
  84. if (leap) monaccu(2) = monaccu(2) + 1
  85. do jmon = 3 , 12
  86. monaccu(jmon) = monaccu(jmon-1) + mondays(jmon)
  87. enddo
  88. kmon = 1
  89. id001 = id001 + 1
  90. do while (id001 > monaccu(kmon))
  91. kmon = kmon + 1
  92. enddo
  93. kday = id001 - monaccu(kmon-1)
  94. istp = mod(kstep,ktspd)
  95. kmin = (istp * 1440) / ktspd
  96. khou = kmin / 60
  97. kmin = mod(kmin,60)
  98. return
  99. end subroutine step2cal
  100. ! ===================
  101. ! SUBROUTINE CAL2STEP
  102. ! ===================
  103. subroutine cal2step(kstep,ktspd,kyea,kmon,kday,khou,kmin)
  104. use calmod
  105. implicit none
  106. integer, intent(OUT) :: kstep ! time step since simulation start
  107. integer, intent(IN ) :: ktspd ! time steps per day
  108. integer, intent(IN ) :: kyea ! current year of simulation
  109. integer, intent(IN ) :: kmon ! current month of simulation
  110. integer, intent(IN ) :: kday ! current day of simulation
  111. integer, intent(IN ) :: khou ! current hour of simulation
  112. integer, intent(IN ) :: kmin ! current minute of simulation
  113. integer :: idall
  114. integer :: ilp
  115. integer :: iy400,id400
  116. integer :: iy100,id100
  117. integer :: iy004,id004
  118. integer :: jmon
  119. logical :: leap
  120. iy400 = kyea / 400 ! segment [400]
  121. id400 = mod(kyea ,400) ! year in segment [0..399]
  122. iy100 = id400 / 100 ! century [0,1,2,3]
  123. id100 = mod(id400,100) ! year in century [0..99]
  124. iy004 = id100 / 4 ! tetrade [0..24]
  125. id004 = mod(id100, 4) ! year in tetrade [0,1,2,3]
  126. leap = (id004 == 0 .and. (id100 /= 0 .or. id400 == 0))
  127. ilp = -1
  128. if (id004 > 0) ilp = ilp + 1
  129. if (iy100 > 0 .and. id100 == 0 ) ilp = ilp + 1
  130. monaccu(0) = mondays(0)
  131. monaccu(1) = mondays(1)
  132. monaccu(2) = mondays(1) + mondays(2)
  133. if (leap) monaccu(2) = monaccu(2) + 1
  134. do jmon = 3 , 12
  135. monaccu(jmon) = monaccu(jmon-1) + mondays(jmon)
  136. enddo
  137. idall = iy400 * ny400d + iy100 * ny100d + iy004 * ny004d &
  138. + id004 * ny001d + monaccu(kmon-1)+ kday + ilp
  139. kstep = ktspd * idall + (ktspd * (khou * 60 + kmin)) / 1440
  140. return
  141. end subroutine cal2step
  142. ! =====================
  143. ! SUBROUTINE STEP2CAL30
  144. ! =====================
  145. subroutine step2cal30(kstep,ktspd,kyea,kmon,kday,khou,kmin)
  146. use calmod
  147. implicit none
  148. integer, intent(IN ) :: kstep ! time step since simulation start
  149. integer, intent(IN ) :: ktspd ! time steps per day
  150. integer, intent(OUT) :: kyea ! current year of simulation
  151. integer, intent(OUT) :: kmon ! current month of simulation
  152. integer, intent(OUT) :: kday ! current day of simulation
  153. integer, intent(OUT) :: khou ! current hour of simulation
  154. integer, intent(OUT) :: kmin ! current minute of simulation
  155. integer :: idall
  156. integer :: istp
  157. idall = kstep / ktspd
  158. kyea = idall / 360
  159. idall = mod(idall,360)
  160. kmon = idall / 30 + 1
  161. kday = mod(idall, 30) + 1
  162. istp = mod(kstep,ktspd)
  163. kmin = (istp * 1440) / ktspd
  164. khou = kmin / 60
  165. kmin = mod(kmin,60)
  166. return
  167. end subroutine step2cal30
  168. ! =====================
  169. ! SUBROUTINE CAL2STEP30
  170. ! =====================
  171. subroutine cal2step30(kstep,ktspd,kyea,kmon,kday,khou,kmin)
  172. use calmod
  173. implicit none
  174. integer, intent(OUT) :: kstep ! time step since simulation start
  175. integer, intent(IN ) :: ktspd ! time steps per day
  176. integer, intent(IN ) :: kyea ! current year of simulation
  177. integer, intent(IN ) :: kmon ! current month of simulation
  178. integer, intent(IN ) :: kday ! current day of simulation
  179. integer, intent(IN ) :: khou ! current hour of simulation
  180. integer, intent(IN ) :: kmin ! current minute of simulation
  181. kstep = ktspd * (kyea * 360 + (kmon-1) * 30 + kday - 1) &
  182. +(ktspd * (khou * 60 + kmin)) / 1440
  183. return
  184. end subroutine cal2step30
  185. program caltest
  186. use calmod
  187. parameter (nstep=100)
  188. do istep = 1 , nstep
  189. call step2cal(istep,32,iyy,imm,idd,ihh,imi)
  190. call cal2step(jstep,32,iyy,imm,idd,ihh,imi)
  191. if (imm==2 .and. idd > 28 .and. ihh == 0 .and. imi == 0) &
  192. write (*,1000) istep,jstep,istep/32+1,iyy,imm,idd,ihh,imi
  193. ! if (iyy == 3 .and. imm == 12) &
  194. ! write (*,1000) istep,jstep,istep/32+1,iyy,imm,idd,ihh,imi
  195. ! if (istep > 1215470) &
  196. ! write (*,1000) istep,jstep,istep/32+1,iyy,imm,idd,ihh,imi
  197. if (istep /= jstep) then
  198. write (*,1000) istep,jstep,istep/32+1,iyy,imm,idd,ihh,imi
  199. stop
  200. endif
  201. enddo
  202. 1000 format(2i10,i8,i5,i3,i3,i3,i3)
  203. print *,'monaccu'
  204. do j = 0,12
  205. print '(i2,i4)',j,monaccu(j)
  206. enddo
  207. print *,'monaccu'
  208. print *,'enter date1 (YYYY MM DD)'
  209. read (*,'(i4,i3,i3)') iy1,im1,id1
  210. print *,'enter date2 (YYYY MM DD)'
  211. read (*,'(i4,i3,i3)') iy2,im2,id2
  212. call cal2step(istep1,32,iy1,im1,id1,0,0)
  213. call cal2step(istep2,32,iy2,im2,id2,0,0)
  214. idd = (istep2-istep1)/32
  215. idy = idd / 365
  216. print *,idd,' Days or ',idy,' Years'
  217. print *,'Weekday is ',nweekday(istep1/32)
  218. print *,'Weekday is ',nweekday(istep2/32)
  219. stop
  220. end