No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

1108 líneas
30 KiB

  1. module.exports = jMoment
  2. var moment = require('moment/moment')
  3. , jalaali = require('jalaali-js')
  4. /************************************
  5. Constants
  6. ************************************/
  7. var formattingTokens = /(\[[^\[]*\])|(\\)?j(Mo|MM?M?M?|Do|DDDo|DD?D?D?|w[o|w]?|YYYYY|YYYY|YY|gg(ggg?)?|)|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g
  8. , localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS?|LL?L?L?|l{1,4})/g
  9. , parseTokenOneOrTwoDigits = /\d\d?/
  10. , parseTokenOneToThreeDigits = /\d{1,3}/
  11. , parseTokenThreeDigits = /\d{3}/
  12. , parseTokenFourDigits = /\d{1,4}/
  13. , parseTokenSixDigits = /[+\-]?\d{1,6}/
  14. , parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i
  15. , parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i
  16. , parseTokenT = /T/i
  17. , parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/
  18. , symbolMap = {
  19. '1': '۱',
  20. '2': '۲',
  21. '3': '۳',
  22. '4': '۴',
  23. '5': '۵',
  24. '6': '۶',
  25. '7': '۷',
  26. '8': '۸',
  27. '9': '۹',
  28. '0': '۰'
  29. }
  30. , numberMap = {
  31. '۱': '1',
  32. '۲': '2',
  33. '۳': '3',
  34. '۴': '4',
  35. '۵': '5',
  36. '۶': '6',
  37. '۷': '7',
  38. '۸': '8',
  39. '۹': '9',
  40. '۰': '0'
  41. }
  42. , unitAliases =
  43. { jm: 'jmonth'
  44. , jmonths: 'jmonth'
  45. , jy: 'jyear'
  46. , jyears: 'jyear'
  47. }
  48. , formatFunctions = {}
  49. , ordinalizeTokens = 'DDD w M D'.split(' ')
  50. , paddedTokens = 'M D w'.split(' ')
  51. , formatTokenFunctions =
  52. { jM: function () {
  53. return this.jMonth() + 1
  54. }
  55. , jMMM: function (format) {
  56. return this.localeData().jMonthsShort(this, format)
  57. }
  58. , jMMMM: function (format) {
  59. return this.localeData().jMonths(this, format)
  60. }
  61. , jD: function () {
  62. return this.jDate()
  63. }
  64. , jDDD: function () {
  65. return this.jDayOfYear()
  66. }
  67. , jw: function () {
  68. return this.jWeek()
  69. }
  70. , jYY: function () {
  71. return leftZeroFill(this.jYear() % 100, 2)
  72. }
  73. , jYYYY: function () {
  74. return leftZeroFill(this.jYear(), 4)
  75. }
  76. , jYYYYY: function () {
  77. return leftZeroFill(this.jYear(), 5)
  78. }
  79. , jgg: function () {
  80. return leftZeroFill(this.jWeekYear() % 100, 2)
  81. }
  82. , jgggg: function () {
  83. return this.jWeekYear()
  84. }
  85. , jggggg: function () {
  86. return leftZeroFill(this.jWeekYear(), 5)
  87. }
  88. }
  89. function padToken(func, count) {
  90. return function (a) {
  91. return leftZeroFill(func.call(this, a), count)
  92. }
  93. }
  94. function ordinalizeToken(func, period) {
  95. return function (a) {
  96. return this.localeData().ordinal(func.call(this, a), period)
  97. }
  98. }
  99. (function () {
  100. var i
  101. while (ordinalizeTokens.length) {
  102. i = ordinalizeTokens.pop()
  103. formatTokenFunctions['j' + i + 'o'] = ordinalizeToken(formatTokenFunctions['j' + i], i)
  104. }
  105. while (paddedTokens.length) {
  106. i = paddedTokens.pop()
  107. formatTokenFunctions['j' + i + i] = padToken(formatTokenFunctions['j' + i], 2)
  108. }
  109. formatTokenFunctions.jDDDD = padToken(formatTokenFunctions.jDDD, 3)
  110. }())
  111. /************************************
  112. Helpers
  113. ************************************/
  114. function extend(a, b) {
  115. var key
  116. for (key in b)
  117. if (b.hasOwnProperty(key))
  118. a[key] = b[key]
  119. return a
  120. }
  121. function leftZeroFill(number, targetLength) {
  122. var output = number + ''
  123. while (output.length < targetLength)
  124. output = '0' + output
  125. return output
  126. }
  127. function isArray(input) {
  128. return Object.prototype.toString.call(input) === '[object Array]'
  129. }
  130. // function compareArrays(array1, array2) {
  131. // var len = Math.min(array1.length, array2.length)
  132. // , lengthDiff = Math.abs(array1.length - array2.length)
  133. // , diffs = 0
  134. // , i
  135. // for (i = 0; i < len; i += 1)
  136. // if (~~array1[i] !== ~~array2[i])
  137. // diffs += 1
  138. // return diffs + lengthDiff
  139. // }
  140. function normalizeUnits(units) {
  141. if (units) {
  142. var lowered = units.toLowerCase()
  143. units = unitAliases[lowered] || lowered
  144. }
  145. return units
  146. }
  147. function setDate(m, year, month, date) {
  148. var d = m._d
  149. if (isNaN(year)) {
  150. m._isValid = false
  151. }
  152. if (m._isUTC) {
  153. /*eslint-disable new-cap*/
  154. m._d = new Date(Date.UTC(year, month, date,
  155. d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds()))
  156. /*eslint-enable new-cap*/
  157. } else {
  158. m._d = new Date(year, month, date,
  159. d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds())
  160. }
  161. }
  162. function objectCreate(parent) {
  163. function F() {}
  164. F.prototype = parent
  165. return new F()
  166. }
  167. function getPrototypeOf(object) {
  168. if (Object.getPrototypeOf)
  169. return Object.getPrototypeOf(object)
  170. else if (''.__proto__)
  171. return object.__proto__
  172. else
  173. return object.constructor.prototype
  174. }
  175. /************************************
  176. Languages
  177. ************************************/
  178. extend(getPrototypeOf(moment.localeData()),
  179. { _jMonths: [ 'Farvardin'
  180. , 'Ordibehesht'
  181. , 'Khordaad'
  182. , 'Tir'
  183. , 'Amordaad'
  184. , 'Shahrivar'
  185. , 'Mehr'
  186. , 'Aabaan'
  187. , 'Aazar'
  188. , 'Dey'
  189. , 'Bahman'
  190. , 'Esfand'
  191. ]
  192. , jMonths: function (m) {
  193. return this._jMonths[m.jMonth()]
  194. }
  195. , _jMonthsShort: [ 'Far'
  196. , 'Ord'
  197. , 'Kho'
  198. , 'Tir'
  199. , 'Amo'
  200. , 'Sha'
  201. , 'Meh'
  202. , 'Aab'
  203. , 'Aaz'
  204. , 'Dey'
  205. , 'Bah'
  206. , 'Esf'
  207. ]
  208. , jMonthsShort: function (m) {
  209. return this._jMonthsShort[m.jMonth()]
  210. }
  211. , jMonthsParse: function (monthName) {
  212. var i
  213. , mom
  214. , regex
  215. if (!this._jMonthsParse)
  216. this._jMonthsParse = []
  217. for (i = 0; i < 12; i += 1) {
  218. // Make the regex if we don't have it already.
  219. if (!this._jMonthsParse[i]) {
  220. mom = jMoment([2000, (2 + i) % 12, 25])
  221. regex = '^' + this.jMonths(mom, '') + '|^' + this.jMonthsShort(mom, '')
  222. this._jMonthsParse[i] = new RegExp(regex.replace('.', ''), 'i')
  223. }
  224. // Test the regex.
  225. if (this._jMonthsParse[i].test(monthName))
  226. return i
  227. }
  228. }
  229. }
  230. )
  231. /************************************
  232. Formatting
  233. ************************************/
  234. function makeFormatFunction(format) {
  235. var array = format.match(formattingTokens)
  236. , length = array.length
  237. , i
  238. for (i = 0; i < length; i += 1)
  239. if (formatTokenFunctions[array[i]])
  240. array[i] = formatTokenFunctions[array[i]]
  241. return function (mom) {
  242. var output = ''
  243. for (i = 0; i < length; i += 1)
  244. output += array[i] instanceof Function ? '[' + array[i].call(mom, format) + ']' : array[i]
  245. return output
  246. }
  247. }
  248. /************************************
  249. Parsing
  250. ************************************/
  251. function getParseRegexForToken(token, config) {
  252. switch (token) {
  253. case 'jDDDD':
  254. return parseTokenThreeDigits
  255. case 'jYYYY':
  256. return parseTokenFourDigits
  257. case 'jYYYYY':
  258. return parseTokenSixDigits
  259. case 'jDDD':
  260. return parseTokenOneToThreeDigits
  261. case 'jMMM':
  262. case 'jMMMM':
  263. return parseTokenWord
  264. case 'jMM':
  265. case 'jDD':
  266. case 'jYY':
  267. case 'jM':
  268. case 'jD':
  269. return parseTokenOneOrTwoDigits
  270. case 'DDDD':
  271. return parseTokenThreeDigits
  272. case 'YYYY':
  273. return parseTokenFourDigits
  274. case 'YYYYY':
  275. return parseTokenSixDigits
  276. case 'S':
  277. case 'SS':
  278. case 'SSS':
  279. case 'DDD':
  280. return parseTokenOneToThreeDigits
  281. case 'MMM':
  282. case 'MMMM':
  283. case 'dd':
  284. case 'ddd':
  285. case 'dddd':
  286. return parseTokenWord
  287. case 'a':
  288. case 'A':
  289. return moment.localeData(config._l)._meridiemParse
  290. case 'X':
  291. return parseTokenTimestampMs
  292. case 'Z':
  293. case 'ZZ':
  294. return parseTokenTimezone
  295. case 'T':
  296. return parseTokenT
  297. case 'MM':
  298. case 'DD':
  299. case 'YY':
  300. case 'HH':
  301. case 'hh':
  302. case 'mm':
  303. case 'ss':
  304. case 'M':
  305. case 'D':
  306. case 'd':
  307. case 'H':
  308. case 'h':
  309. case 'm':
  310. case 's':
  311. return parseTokenOneOrTwoDigits
  312. default:
  313. return new RegExp(token.replace('\\', ''))
  314. }
  315. }
  316. function addTimeToArrayFromToken(token, input, config) {
  317. var a
  318. , datePartArray = config._a
  319. switch (token) {
  320. case 'jM':
  321. case 'jMM':
  322. datePartArray[1] = input == null ? 0 : ~~input - 1
  323. break
  324. case 'jMMM':
  325. case 'jMMMM':
  326. a = moment.localeData(config._l).jMonthsParse(input)
  327. if (a != null)
  328. datePartArray[1] = a
  329. else
  330. config._isValid = false
  331. break
  332. case 'jD':
  333. case 'jDD':
  334. case 'jDDD':
  335. case 'jDDDD':
  336. if (input != null)
  337. datePartArray[2] = ~~input
  338. break
  339. case 'jYY':
  340. datePartArray[0] = ~~input + (~~input > 47 ? 1300 : 1400)
  341. break
  342. case 'jYYYY':
  343. case 'jYYYYY':
  344. datePartArray[0] = ~~input
  345. }
  346. if (input == null)
  347. config._isValid = false
  348. }
  349. function dateFromArray(config) {
  350. var g
  351. , j
  352. , jy = config._a[0]
  353. , jm = config._a[1]
  354. , jd = config._a[2]
  355. if ((jy == null) && (jm == null) && (jd == null))
  356. return [0, 0, 1]
  357. jy = jy != null ? jy : 0
  358. jm = jm != null ? jm : 0
  359. jd = jd != null ? jd : 1
  360. if (jd < 1 || jd > jMoment.jDaysInMonth(jy, jm) || jm < 0 || jm > 11)
  361. config._isValid = false
  362. g = toGregorian(jy, jm, jd)
  363. j = toJalaali(g.gy, g.gm, g.gd)
  364. if (isNaN(g.gy))
  365. config._isValid = false
  366. config._jDiff = 0
  367. if (~~j.jy !== jy)
  368. config._jDiff += 1
  369. if (~~j.jm !== jm)
  370. config._jDiff += 1
  371. if (~~j.jd !== jd)
  372. config._jDiff += 1
  373. return [g.gy, g.gm, g.gd]
  374. }
  375. function makeDateFromStringAndFormat(config) {
  376. var tokens = config._f.match(formattingTokens)
  377. , string = config._i + ''
  378. , len = tokens.length
  379. , i
  380. , token
  381. , parsedInput
  382. config._a = []
  383. for (i = 0; i < len; i += 1) {
  384. token = tokens[i]
  385. parsedInput = (getParseRegexForToken(token, config).exec(string) || [])[0]
  386. if (parsedInput)
  387. string = string.slice(string.indexOf(parsedInput) + parsedInput.length)
  388. if (formatTokenFunctions[token])
  389. addTimeToArrayFromToken(token, parsedInput, config)
  390. }
  391. if (string)
  392. config._il = string
  393. return dateFromArray(config)
  394. }
  395. function makeDateFromStringAndArray(config, utc) {
  396. var len = config._f.length
  397. , i
  398. , format
  399. , tempMoment
  400. , bestMoment
  401. , currentScore
  402. , scoreToBeat
  403. if (len === 0) {
  404. return makeMoment(new Date(NaN))
  405. }
  406. for (i = 0; i < len; i += 1) {
  407. format = config._f[i]
  408. currentScore = 0
  409. tempMoment = makeMoment(config._i, format, config._l, config._strict, utc)
  410. if (!tempMoment.isValid()) continue
  411. // currentScore = compareArrays(tempMoment._a, tempMoment.toArray())
  412. currentScore += tempMoment._jDiff
  413. if (tempMoment._il)
  414. currentScore += tempMoment._il.length
  415. if (scoreToBeat == null || currentScore < scoreToBeat) {
  416. scoreToBeat = currentScore
  417. bestMoment = tempMoment
  418. }
  419. }
  420. return bestMoment
  421. }
  422. function removeParsedTokens(config) {
  423. var string = config._i + ''
  424. , input = ''
  425. , format = ''
  426. , array = config._f.match(formattingTokens)
  427. , len = array.length
  428. , i
  429. , match
  430. , parsed
  431. for (i = 0; i < len; i += 1) {
  432. match = array[i]
  433. parsed = (getParseRegexForToken(match, config).exec(string) || [])[0]
  434. if (parsed)
  435. string = string.slice(string.indexOf(parsed) + parsed.length)
  436. if (!(formatTokenFunctions[match] instanceof Function)) {
  437. format += match
  438. if (parsed)
  439. input += parsed
  440. }
  441. }
  442. config._i = input
  443. config._f = format
  444. }
  445. /************************************
  446. Week of Year
  447. ************************************/
  448. function jWeekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
  449. var end = firstDayOfWeekOfYear - firstDayOfWeek
  450. , daysToDayOfWeek = firstDayOfWeekOfYear - mom.day()
  451. , adjustedMoment
  452. if (daysToDayOfWeek > end) {
  453. daysToDayOfWeek -= 7
  454. }
  455. if (daysToDayOfWeek < end - 7) {
  456. daysToDayOfWeek += 7
  457. }
  458. adjustedMoment = jMoment(mom).add(daysToDayOfWeek, 'd')
  459. return { week: Math.ceil(adjustedMoment.jDayOfYear() / 7)
  460. , year: adjustedMoment.jYear()
  461. }
  462. }
  463. /************************************
  464. Top Level Functions
  465. ************************************/
  466. var maxTimestamp = 57724432199999
  467. function makeMoment(input, format, lang, strict, utc) {
  468. if (typeof lang === 'boolean') {
  469. strict = lang
  470. lang = undefined
  471. }
  472. if (format && typeof format === 'string')
  473. format = fixFormat(format, moment)
  474. var config =
  475. { _i: input
  476. , _f: format
  477. , _l: lang
  478. , _strict: strict
  479. , _isUTC: utc
  480. }
  481. , date
  482. , m
  483. , jm
  484. , origInput = input
  485. , origFormat = format
  486. if (format) {
  487. if (isArray(format)) {
  488. return makeDateFromStringAndArray(config, utc)
  489. } else {
  490. date = makeDateFromStringAndFormat(config)
  491. removeParsedTokens(config)
  492. format = 'YYYY-MM-DD-' + config._f
  493. input = leftZeroFill(date[0], 4) + '-'
  494. + leftZeroFill(date[1] + 1, 2) + '-'
  495. + leftZeroFill(date[2], 2) + '-'
  496. + config._i
  497. }
  498. }
  499. if (utc)
  500. m = moment.utc(input, format, lang, strict)
  501. else
  502. m = moment(input, format, lang, strict)
  503. if (config._isValid === false)
  504. m._isValid = false
  505. m._jDiff = config._jDiff || 0
  506. jm = objectCreate(jMoment.fn)
  507. extend(jm, m)
  508. if (strict && format && jm.isValid()) {
  509. jm._isValid = jm.format(origFormat) === origInput
  510. }
  511. if (m._d.getTime() > maxTimestamp) {
  512. jm._isValid = false
  513. }
  514. return jm
  515. }
  516. function jMoment(input, format, lang, strict) {
  517. return makeMoment(input, format, lang, strict, false)
  518. }
  519. extend(jMoment, moment)
  520. jMoment.fn = objectCreate(moment.fn)
  521. jMoment.utc = function (input, format, lang, strict) {
  522. return makeMoment(input, format, lang, strict, true)
  523. }
  524. jMoment.unix = function (input) {
  525. return makeMoment(input * 1000)
  526. }
  527. /************************************
  528. jMoment Prototype
  529. ************************************/
  530. function fixFormat(format, _moment) {
  531. var i = 5
  532. var replace = function (input) {
  533. return _moment.localeData().longDateFormat(input) || input
  534. }
  535. while (i > 0 && localFormattingTokens.test(format)) {
  536. i -= 1
  537. format = format.replace(localFormattingTokens, replace)
  538. }
  539. return format
  540. }
  541. jMoment.fn.format = function (format) {
  542. if (format) {
  543. format = fixFormat(format, this)
  544. if (!formatFunctions[format]) {
  545. formatFunctions[format] = makeFormatFunction(format)
  546. }
  547. format = formatFunctions[format](this)
  548. }
  549. return moment.fn.format.call(this, format)
  550. }
  551. jMoment.fn.jYear = function (input) {
  552. var lastDay
  553. , j
  554. , g
  555. if (typeof input === 'number') {
  556. j = toJalaali(this.year(), this.month(), this.date())
  557. lastDay = Math.min(j.jd, jMoment.jDaysInMonth(input, j.jm))
  558. g = toGregorian(input, j.jm, lastDay)
  559. setDate(this, g.gy, g.gm, g.gd)
  560. moment.updateOffset(this)
  561. return this
  562. } else {
  563. return toJalaali(this.year(), this.month(), this.date()).jy
  564. }
  565. }
  566. jMoment.fn.jMonth = function (input) {
  567. var lastDay
  568. , j
  569. , g
  570. if (input != null) {
  571. if (typeof input === 'string') {
  572. input = this.localeData().jMonthsParse(input)
  573. if (typeof input !== 'number')
  574. return this
  575. }
  576. j = toJalaali(this.year(), this.month(), this.date())
  577. lastDay = Math.min(j.jd, jMoment.jDaysInMonth(j.jy, input))
  578. this.jYear(j.jy + div(input, 12))
  579. input = mod(input, 12)
  580. if (input < 0) {
  581. input += 12
  582. this.jYear(this.jYear() - 1)
  583. }
  584. g = toGregorian(this.jYear(), input, lastDay)
  585. setDate(this, g.gy, g.gm, g.gd)
  586. moment.updateOffset(this)
  587. return this
  588. } else {
  589. return toJalaali(this.year(), this.month(), this.date()).jm
  590. }
  591. }
  592. jMoment.fn.jDate = function (input) {
  593. var j
  594. , g
  595. if (typeof input === 'number') {
  596. j = toJalaali(this.year(), this.month(), this.date())
  597. g = toGregorian(j.jy, j.jm, input)
  598. setDate(this, g.gy, g.gm, g.gd)
  599. moment.updateOffset(this)
  600. return this
  601. } else {
  602. return toJalaali(this.year(), this.month(), this.date()).jd
  603. }
  604. }
  605. jMoment.fn.jDayOfYear = function (input) {
  606. var dayOfYear = Math.round((jMoment(this).startOf('day') - jMoment(this).startOf('jYear')) / 864e5) + 1
  607. return input == null ? dayOfYear : this.add(input - dayOfYear, 'd')
  608. }
  609. jMoment.fn.jWeek = function (input) {
  610. var week = jWeekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).week
  611. return input == null ? week : this.add((input - week) * 7, 'd')
  612. }
  613. jMoment.fn.jWeekYear = function (input) {
  614. var year = jWeekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year
  615. return input == null ? year : this.add(input - year, 'y')
  616. }
  617. jMoment.fn.add = function (val, units) {
  618. var temp
  619. if (units !== null && !isNaN(+units)) {
  620. temp = val
  621. val = units
  622. units = temp
  623. }
  624. units = normalizeUnits(units)
  625. if (units === 'jyear') {
  626. this.jYear(this.jYear() + val)
  627. } else if (units === 'jmonth') {
  628. this.jMonth(this.jMonth() + val)
  629. } else {
  630. moment.fn.add.call(this, val, units)
  631. if (isNaN(this.jYear())) {
  632. this._isValid = false
  633. }
  634. }
  635. return this
  636. }
  637. jMoment.fn.subtract = function (val, units) {
  638. var temp
  639. if (units !== null && !isNaN(+units)) {
  640. temp = val
  641. val = units
  642. units = temp
  643. }
  644. units = normalizeUnits(units)
  645. if (units === 'jyear') {
  646. this.jYear(this.jYear() - val)
  647. } else if (units === 'jmonth') {
  648. this.jMonth(this.jMonth() - val)
  649. } else {
  650. moment.fn.subtract.call(this, val, units)
  651. }
  652. return this
  653. }
  654. jMoment.fn.startOf = function (units) {
  655. units = normalizeUnits(units)
  656. if (units === 'jyear' || units === 'jmonth') {
  657. if (units === 'jyear') {
  658. this.jMonth(0)
  659. }
  660. this.jDate(1)
  661. this.hours(0)
  662. this.minutes(0)
  663. this.seconds(0)
  664. this.milliseconds(0)
  665. return this
  666. } else {
  667. return moment.fn.startOf.call(this, units)
  668. }
  669. }
  670. jMoment.fn.endOf = function (units) {
  671. units = normalizeUnits(units)
  672. if (units === undefined || units === 'milisecond') {
  673. return this
  674. }
  675. return this.startOf(units).add(1, (units === 'isoweek' ? 'week' : units)).subtract(1, 'ms')
  676. }
  677. jMoment.fn.isSame = function (other, units) {
  678. units = normalizeUnits(units)
  679. if (units === 'jyear' || units === 'jmonth') {
  680. return moment.fn.isSame.call(this.startOf(units), other.startOf(units))
  681. }
  682. return moment.fn.isSame.call(this, other, units)
  683. }
  684. jMoment.fn.clone = function () {
  685. return jMoment(this)
  686. }
  687. jMoment.fn.jYears = jMoment.fn.jYear
  688. jMoment.fn.jMonths = jMoment.fn.jMonth
  689. jMoment.fn.jDates = jMoment.fn.jDate
  690. jMoment.fn.jWeeks = jMoment.fn.jWeek
  691. /************************************
  692. jMoment Statics
  693. ************************************/
  694. jMoment.jDaysInMonth = function (year, month) {
  695. year += div(month, 12)
  696. month = mod(month, 12)
  697. if (month < 0) {
  698. month += 12
  699. year -= 1
  700. }
  701. if (month < 6) {
  702. return 31
  703. } else if (month < 11) {
  704. return 30
  705. } else if (jMoment.jIsLeapYear(year)) {
  706. return 30
  707. } else {
  708. return 29
  709. }
  710. }
  711. jMoment.jIsLeapYear = jalaali.isLeapJalaaliYear
  712. jMoment.loadPersian = function (args) {
  713. var usePersianDigits = args !== undefined && args.hasOwnProperty('usePersianDigits') ? args.usePersianDigits : false
  714. var dialect = args !== undefined && args.hasOwnProperty('dialect') ? args.dialect : 'persian'
  715. moment.locale('fa')
  716. moment.updateLocale('fa'
  717. , { months: ('ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر').split('_')
  718. , monthsShort: ('ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر').split('_')
  719. , weekdays:
  720. {
  721. 'persian': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_آدینه_شنبه').split('_'),
  722. 'persian-modern': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه').split('_')
  723. }[dialect]
  724. , weekdaysShort:
  725. {
  726. 'persian': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_آدینه_شنبه').split('_'),
  727. 'persian-modern': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه').split('_')
  728. }[dialect]
  729. , weekdaysMin:
  730. {
  731. 'persian': 'ی_د_س_چ_پ_آ_ش'.split('_'),
  732. 'persian-modern': 'ی_د_س_چ_پ_ج_ش'.split('_')
  733. }[dialect]
  734. , longDateFormat:
  735. { LT: 'HH:mm'
  736. , L: 'jYYYY/jMM/jDD'
  737. , LL: 'jD jMMMM jYYYY'
  738. , LLL: 'jD jMMMM jYYYY LT'
  739. , LLLL: 'dddd، jD jMMMM jYYYY LT'
  740. }
  741. , calendar:
  742. { sameDay: '[امروز ساعت] LT'
  743. , nextDay: '[فردا ساعت] LT'
  744. , nextWeek: 'dddd [ساعت] LT'
  745. , lastDay: '[دیروز ساعت] LT'
  746. , lastWeek: 'dddd [ی پیش ساعت] LT'
  747. , sameElse: 'L'
  748. }
  749. , relativeTime:
  750. { future: 'در %s'
  751. , past: '%s پیش'
  752. , s: 'چند ثانیه'
  753. , m: '1 دقیقه'
  754. , mm: '%d دقیقه'
  755. , h: '1 ساعت'
  756. , hh: '%d ساعت'
  757. , d: '1 روز'
  758. , dd: '%d روز'
  759. , M: '1 ماه'
  760. , MM: '%d ماه'
  761. , y: '1 سال'
  762. , yy: '%d سال'
  763. }
  764. , preparse: function (string) {
  765. if (usePersianDigits) {
  766. return string.replace(/[۰-۹]/g, function (match) {
  767. return numberMap[match]
  768. }).replace(/،/g, ',')
  769. }
  770. return string
  771. }
  772. , postformat: function (string) {
  773. if (usePersianDigits) {
  774. return string.replace(/\d/g, function (match) {
  775. return symbolMap[match]
  776. }).replace(/,/g, '،')
  777. }
  778. return string
  779. }
  780. , ordinal: '%dم'
  781. , week:
  782. { dow: 6 // Saturday is the first day of the week.
  783. , doy: 12 // The week that contains Jan 1st is the first week of the year.
  784. }
  785. , meridiem: function (hour) {
  786. return hour < 12 ? 'ق.ظ' : 'ب.ظ'
  787. }
  788. , jMonths:
  789. {
  790. 'persian': ('فروردین_اردیبهشت_خرداد_تیر_امرداد_شهریور_مهر_آبان_آذر_دی_بهمن_اسفند').split('_'),
  791. 'persian-modern': ('فروردین_اردیبهشت_خرداد_تیر_مرداد_شهریور_مهر_آبان_آذر_دی_بهمن_اسفند').split('_')
  792. }[dialect]
  793. , jMonthsShort:
  794. {
  795. 'persian': 'فرو_ارد_خرد_تیر_امر_شهر_مهر_آبا_آذر_دی_بهم_اسف'.split('_'),
  796. 'persian-modern': 'فرو_ارد_خرد_تیر_مرد_شهر_مهر_آبا_آذر_دی_بهم_اسف'.split('_')
  797. }[dialect]
  798. }
  799. )
  800. }
  801. jMoment.loadPersian_dari = function (args) {
  802. var usePersianDigits = args !== undefined && args.hasOwnProperty('usePersianDigits') ? args.usePersianDigits : false
  803. var dialect = args !== undefined && args.hasOwnProperty('dialect') ? args.dialect : 'persian-dari'
  804. moment.locale('fa-af')
  805. moment.updateLocale('fa-af'
  806. , { months: ('جنوری_فبروری_مارچ_اپریل_می_جون_جولای_آگست_سپتمبر_اکتوبر_نومبر_دیسمبر').split('_')
  807. , monthsShort: ('جنوری_فبروری_مارچ_اپریل_می_جون_جولای_آگست_سپتمبر_اکتوبر_نومبر_دیسمبر').split('_')
  808. , weekdays:
  809. {
  810. 'persian': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_آدینه_شنبه').split('_'),
  811. 'persian-modern': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه').split('_')
  812. }[dialect]
  813. , weekdaysShort:
  814. {
  815. 'persian': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_آدینه_شنبه').split('_'),
  816. 'persian-modern': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه').split('_')
  817. }[dialect]
  818. , weekdaysMin:
  819. {
  820. 'persian': 'ی_د_س_چ_پ_آ_ش'.split('_'),
  821. 'persian-modern': 'ی_د_س_چ_پ_ج_ش'.split('_')
  822. }[dialect]
  823. , longDateFormat:
  824. { LT: 'HH:mm'
  825. , L: 'jYYYY/jMM/jDD'
  826. , LL: 'jD jMMMM jYYYY'
  827. , LLL: 'jD jMMMM jYYYY LT'
  828. , LLLL: 'dddd، jD jMMMM jYYYY LT'
  829. }
  830. , calendar:
  831. { sameDay: '[امروز ساعت] LT'
  832. , nextDay: '[فردا ساعت] LT'
  833. , nextWeek: 'dddd [ساعت] LT'
  834. , lastDay: '[دیروز ساعت] LT'
  835. , lastWeek: 'dddd [ی پیش ساعت] LT'
  836. , sameElse: 'L'
  837. }
  838. , relativeTime:
  839. { future: 'در %s'
  840. , past: '%s پیش'
  841. , s: 'چند ثانیه'
  842. , m: '1 دقیقه'
  843. , mm: '%d دقیقه'
  844. , h: '1 ساعت'
  845. , hh: '%d ساعت'
  846. , d: '1 روز'
  847. , dd: '%d روز'
  848. , M: '1 ماه'
  849. , MM: '%d ماه'
  850. , y: '1 سال'
  851. , yy: '%d سال'
  852. }
  853. , preparse: function (string) {
  854. if (usePersianDigits) {
  855. return string.replace(/[۰-۹]/g, function (match) {
  856. return numberMap[match]
  857. }).replace(/،/g, ',')
  858. }
  859. return string
  860. }
  861. , postformat: function (string) {
  862. if (usePersianDigits) {
  863. return string.replace(/\d/g, function (match) {
  864. return symbolMap[match]
  865. }).replace(/,/g, '،')
  866. }
  867. return string
  868. }
  869. , ordinal: '%dم'
  870. , week:
  871. { dow: 6 // Saturday is the first day of the week.
  872. , doy: 12 // The week that contains Jan 1st is the first week of the year.
  873. }
  874. , meridiem: function (hour) {
  875. return hour < 12 ? 'ق.ظ' : 'ب.ظ'
  876. }
  877. , jMonths:
  878. {
  879. 'persian-dari': ('حمل_ثور_جوزا_سرطان_اسد_سنبله_میزان_عقرب_قوس_جدی_دلو_حوت').split('_'),
  880. 'persian-modern-dari': ('حمل_ثور_جوزا_سرطان_اسد_سنبله_میزان_عقرب_قوس_جدی_دلو_حوت').split('_')
  881. }[dialect]
  882. , jMonthsShort:
  883. {
  884. 'persian-dari': 'حمل_ثور_جوزا_سرط_اسد_سنب_میز_عقر_قوس_جدی_دلو_حوت'.split('_'),
  885. 'persian-modern-dari': 'حمل_ثور_جوزا_سرط_اسد_سنب_میز_عقر_قوس_جدی_دلو_حوت'.split('_')
  886. }[dialect]
  887. }
  888. )
  889. }
  890. jMoment.loadPashto = function (args) {
  891. var usePersianDigits = args !== undefined && args.hasOwnProperty('usePersianDigits') ? args.usePersianDigits : false
  892. var dialect = args !== undefined && args.hasOwnProperty('dialect') ? args.dialect : 'pashto'
  893. moment.locale('ps-af')
  894. moment.updateLocale('ps-af'
  895. , { months: ('جنوری_فبروری_مارچ_اپریل_می_جون_جولای_آگست_سپتمبر_اکتوبر_نومبر_دیسمبر').split('_')
  896. , monthsShort: ('جنوری_فبروری_مارچ_اپریل_می_جون_جولای_آگست_سپتمبر_اکتوبر_نومبر_دیسمبر').split('_')
  897. , weekdays:
  898. {
  899. 'pashto': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_آدینه_شنبه').split('_'),
  900. 'pashto-modern': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه').split('_')
  901. }[dialect]
  902. , weekdaysShort:
  903. {
  904. 'pashto': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_آدینه_شنبه').split('_'),
  905. 'pashto-modern': ('یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه').split('_')
  906. }[dialect]
  907. , weekdaysMin:
  908. {
  909. 'pashto': 'ی_د_س_چ_پ_آ_ش'.split('_'),
  910. 'pashto-modern': 'ی_د_س_چ_پ_ج_ش'.split('_')
  911. }[dialect]
  912. , longDateFormat:
  913. { LT: 'HH:mm'
  914. , L: 'jYYYY/jMM/jDD'
  915. , LL: 'jD jMMMM jYYYY'
  916. , LLL: 'jD jMMMM jYYYY LT'
  917. , LLLL: 'dddd، jD jMMMM jYYYY LT'
  918. }
  919. , calendar:
  920. { sameDay: '[امروز ساعت] LT'
  921. , nextDay: '[فردا ساعت] LT'
  922. , nextWeek: 'dddd [ساعت] LT'
  923. , lastDay: '[دیروز ساعت] LT'
  924. , lastWeek: 'dddd [ی پیش ساعت] LT'
  925. , sameElse: 'L'
  926. }
  927. , relativeTime:
  928. { future: 'در %s'
  929. , past: '%s پیش'
  930. , s: 'چند ثانیه'
  931. , m: '1 دقیقه'
  932. , mm: '%d دقیقه'
  933. , h: '1 ساعت'
  934. , hh: '%d ساعت'
  935. , d: '1 روز'
  936. , dd: '%d روز'
  937. , M: '1 ماه'
  938. , MM: '%d ماه'
  939. , y: '1 سال'
  940. , yy: '%d سال'
  941. }
  942. , preparse: function (string) {
  943. if (usePersianDigits) {
  944. return string.replace(/[۰-۹]/g, function (match) {
  945. return numberMap[match]
  946. }).replace(/،/g, ',')
  947. }
  948. return string
  949. }
  950. , postformat: function (string) {
  951. if (usePersianDigits) {
  952. return string.replace(/\d/g, function (match) {
  953. return symbolMap[match]
  954. }).replace(/,/g, '،')
  955. }
  956. return string
  957. }
  958. , ordinal: '%dم'
  959. , week:
  960. { dow: 6 // Saturday is the first day of the week.
  961. , doy: 12 // The week that contains Jan 1st is the first week of the year.
  962. }
  963. , meridiem: function (hour) {
  964. return hour < 12 ? 'ق.ظ' : 'ب.ظ'
  965. }
  966. , jMonths:
  967. {
  968. 'pashto': ('وری_غویی_غبرګولی_چنګاښ_زمری_وږی_تله_لړم_لیندی_مرغومی_سلواغه_کب').split('_'),
  969. 'pashto-modern': ('وری_غویی_غبرګولی_چنګاښ_زمری_وږی_تله_لړم_لیندی_مرغومی_سلواغه_کب').split('_')
  970. }[dialect]
  971. , jMonthsShort:
  972. {
  973. 'pashto': 'وری_غوی_غبر_چنګ_زمر_وږی_لړم_لین_مرغ_سلو_کب'.split('_'),
  974. 'pashto-modern': 'وری_غوی_غبر_چنګ_زمر_وږی_لړم_لین_مرغ_سلو_کب'.split('_')
  975. }[dialect]
  976. }
  977. )
  978. }
  979. jMoment.jConvert = { toJalaali: toJalaali
  980. , toGregorian: toGregorian
  981. }
  982. /************************************
  983. Jalaali Conversion
  984. ************************************/
  985. function toJalaali(gy, gm, gd) {
  986. try {
  987. var j = jalaali.toJalaali(gy, gm + 1, gd)
  988. j.jm -= 1
  989. return j
  990. } catch (e) {
  991. return {
  992. jy: NaN
  993. , jm: NaN
  994. , jd: NaN
  995. }
  996. }
  997. }
  998. function toGregorian(jy, jm, jd) {
  999. try {
  1000. var g = jalaali.toGregorian(jy, jm + 1, jd)
  1001. g.gm -= 1
  1002. return g
  1003. } catch (e) {
  1004. return {
  1005. gy: NaN
  1006. , gm: NaN
  1007. , gd: NaN
  1008. }
  1009. }
  1010. }
  1011. /*
  1012. Utility helper functions.
  1013. */
  1014. function div(a, b) {
  1015. return ~~(a / b)
  1016. }
  1017. function mod(a, b) {
  1018. return a - ~~(a / b) * b
  1019. }