| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 | 'use strict'var extend = require('xtend/mutable')module.exports = PostgresIntervalfunction PostgresInterval (raw) {  if (!(this instanceof PostgresInterval)) {    return new PostgresInterval(raw)  }  extend(this, parse(raw))}var properties = ['seconds', 'minutes', 'hours', 'days', 'months', 'years']PostgresInterval.prototype.toPostgres = function () {  var filtered = properties.filter(this.hasOwnProperty, this)  // In addition to `properties`, we need to account for fractions of seconds.  if (this.milliseconds && filtered.indexOf('seconds') < 0) {    filtered.push('seconds')  }  if (filtered.length === 0) return '0'  return filtered    .map(function (property) {      var value = this[property] || 0      // Account for fractional part of seconds,      // remove trailing zeroes.      if (property === 'seconds' && this.milliseconds) {        value = (value + this.milliseconds / 1000).toFixed(6).replace(/\.?0+$/, '')      }      return value + ' ' + property    }, this)    .join(' ')}var propertiesISOEquivalent = {  years: 'Y',  months: 'M',  days: 'D',  hours: 'H',  minutes: 'M',  seconds: 'S'}var dateProperties = ['years', 'months', 'days']var timeProperties = ['hours', 'minutes', 'seconds']// according to ISO 8601PostgresInterval.prototype.toISOString = PostgresInterval.prototype.toISO = function () {  var datePart = dateProperties    .map(buildProperty, this)    .join('')  var timePart = timeProperties    .map(buildProperty, this)    .join('')  return 'P' + datePart + 'T' + timePart  function buildProperty (property) {    var value = this[property] || 0    // Account for fractional part of seconds,    // remove trailing zeroes.    if (property === 'seconds' && this.milliseconds) {      value = (value + this.milliseconds / 1000).toFixed(6).replace(/0+$/, '')    }    return value + propertiesISOEquivalent[property]  }}var NUMBER = '([+-]?\\d+)'var YEAR = NUMBER + '\\s+years?'var MONTH = NUMBER + '\\s+mons?'var DAY = NUMBER + '\\s+days?'var TIME = '([+-])?([\\d]*):(\\d\\d):(\\d\\d)\\.?(\\d{1,6})?'var INTERVAL = new RegExp([YEAR, MONTH, DAY, TIME].map(function (regexString) {  return '(' + regexString + ')?'})  .join('\\s*'))// Positions of values in regex matchvar positions = {  years: 2,  months: 4,  days: 6,  hours: 9,  minutes: 10,  seconds: 11,  milliseconds: 12}// We can use negative timevar negatives = ['hours', 'minutes', 'seconds', 'milliseconds']function parseMilliseconds (fraction) {  // add omitted zeroes  var microseconds = fraction + '000000'.slice(fraction.length)  return parseInt(microseconds, 10) / 1000}function parse (interval) {  if (!interval) return {}  var matches = INTERVAL.exec(interval)  var isNegative = matches[8] === '-'  return Object.keys(positions)    .reduce(function (parsed, property) {      var position = positions[property]      var value = matches[position]      // no empty string      if (!value) return parsed      // milliseconds are actually microseconds (up to 6 digits)      // with omitted trailing zeroes.      value = property === 'milliseconds'        ? parseMilliseconds(value)        : parseInt(value, 10)      // no zeros      if (!value) return parsed      if (isNegative && ~negatives.indexOf(property)) {        value *= -1      }      parsed[property] = value      return parsed    }, {})}
 |