Javascript function to convert decimal years value into years, months and days

后端 未结 4 1705
我在风中等你
我在风中等你 2021-01-14 10:48

I need a function to transform decimal values of years in years, months and days. Ex: 1.5 years = 1 year, 6 month. 2.2527397260273973 years = 2 years, 3 months and 1 day.

4条回答
  •  庸人自扰
    2021-01-14 11:13

    My contribution converts decimal years into time units ranging from eons (billion years) to nanoseconds (billionths of a second), and is output formatted with commas in a slightly chatty style.

    There are many ways to convert time, and the presumptions have to be understood. Here are mine:

    This converts based on 1) an average month having 30.436875 days, per the Gregorian calendar; 2) a month having 730.485 hours average for a 4-year period which includes 1 leap year; and 3) there being 8765.82 hours per year (not 8760). These internal constants won't fit every application, of course, but should be good enough for general use. For example, my function adds about a minute of time to the OP's example of:

    2.2527397260273973 years = 2 years, 3 months and 1 day

    where

    getTimeFromYears( 2.2527397260273973 );
    

    outputs "2 years, 3 months, 1 day and 57 seconds".

    Some units seemed unnecessary, such as weeks when you have days and months, and decades when you have years and centuries, but those can easily be added into the logic. Run the snippet to see the examples.

    function getTimeFromYears( _years ) {
    // to omit a unit from the output, multiply its value by zero; see gyears
    
        "use strict";
    
        var _hoursInEon            = 8765820000000     // eon =         1,000,000,000 years (billion)
            , _hoursInGalacticYear = 2016138600000     // galactic year = 230,000,000 years (230 million)
            , _hoursInEpoch        =    8765820000     // epoch =           1,000,000 years (million)
            , _hoursInMillenium    =       8765820     // millenium =           1,000 years
            , _hoursInCentury      =        876582   
            , _hoursInYear         =          8765.82  // often cited as 8760, or 730 * 12  // 365.2425 days in year
            , _hoursInMonth        =           730.485 // hours average per month for a 4-year period which includes 1 leap year
                                                       // average month has 30.436875 days, Gregorian calendar
            , _hoursInDay          =            24
            , _hoursInHour         =             1
            , _hoursInMinute       =             0.0166666666666667
            , _hoursInSecond       =             0.000277778
            , _hoursInMillisecond  =             0.000000277778       // A millisecond is one-thousandth of a second
            , _hoursInNanosecond   =             0.000000000000277778 // A nanosecond is one-billionth of a second
    
    
            , totalHours = _years * _hoursInYear
            
            , eons   = Math.floor(   totalHours
                        / _hoursInEon )
    
            , gyears = Math.floor( ( totalHours - ( eons * _hoursInEon ) )
                        / _hoursInGalacticYear ) * 0
    
            , epochs = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) )
                        / _hoursInEpoch )
    
            , mills  = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) )
                        / _hoursInMillenium )
    
            , cents  = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) )
                        / _hoursInCentury )
    
            , years  = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) )
                        / _hoursInYear )
        
            , months = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) )
                        / _hoursInMonth )
        
            , days   = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) - ( months * _hoursInMonth ) )
                        / _hoursInDay )
        
            , hours  = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) - ( months * _hoursInMonth ) - ( days * _hoursInDay ) )
                        / _hoursInHour )
        
            , mins  = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) - ( months * _hoursInMonth ) - ( days * _hoursInDay ) - ( hours * _hoursInHour ) )
                        / _hoursInMinute ) 
    
            , secs  = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) - ( months * _hoursInMonth ) - ( days * _hoursInDay ) - ( hours * _hoursInHour ) - ( mins * _hoursInMinute ) )
                        / _hoursInSecond )
    
            , msecs = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) - ( months * _hoursInMonth ) - ( days * _hoursInDay ) - ( hours * _hoursInHour ) - ( mins * _hoursInMinute ) - ( secs * _hoursInSecond ) )
                        / _hoursInMillisecond )
    
            , nsecs = Math.floor( ( totalHours - ( eons * _hoursInEon ) - ( gyears * _hoursInGalacticYear ) - ( epochs * _hoursInEpoch ) - ( mills * _hoursInMillenium ) - ( cents * _hoursInCentury ) - ( years * _hoursInYear ) - ( months * _hoursInMonth ) - ( days * _hoursInDay ) - ( hours * _hoursInHour ) - ( mins * _hoursInMinute ) - ( secs * _hoursInSecond ) - ( msecs * _hoursInMillisecond ) )
                        / _hoursInNanosecond )
    
    
            , _eonsPhrase   = ( eons   < 1 ? '' : eons   === 1 ? '1 eon'           : addCommas( eons   ) + ' eons'           )
            , _gyearsPhrase = ( gyears < 1 ? '' : gyears === 1 ? '1 galactic year' : addCommas( gyears ) + ' galactic years' )
            , _epochsPhrase = ( epochs < 1 ? '' : epochs === 1 ? '1 epoch'         : addCommas( epochs ) + ' epochs'         )
            , _millsPhrase  = ( mills  < 1 ? '' : mills  === 1 ? '1 millenium'     : mills  + ' millenia'  )
            , _centsPhrase  = ( cents  < 1 ? '' : cents  === 1 ? '1 century'       : cents  + ' centuries' )
            , _yearsPhrase  = ( years  < 1 ? '' : years  === 1 ? '1 year'          : years  + ' years'     )
            , _monthsPhrase = ( months < 1 ? '' : months === 1 ? '1 month'         : months + ' months'    )
            , _daysPhrase   = ( days   < 1 ? '' : days   === 1 ? '1 day'           : days   + ' days'      )
            , _hoursPhrase  = ( hours  < 1 ? '' : hours  === 1 ? '1 hour'          : hours  + ' hours'     )
            , _minsPhrase   = ( mins   < 1 ? '' : mins   === 1 ? '1 minute'        : mins   + ' minutes'   )
            , _secsPhrase   = ( secs   < 1 ? '' : secs   === 1 ? '1 second'        : secs   + ' seconds'   )
            , _msecsPhrase  = ( msecs  < 1 ? '' : msecs  === 1 ? '1 millisecond'   : addCommas( msecs ) + ' milliseconds' )
            , _nsecsPhrase  = ( nsecs  < 1 ? '' : nsecs  === 1 ? '1 nanosecond'    : addCommas( nsecs ) + ' nanoseconds'  )
    
            , _phrasePart = new Array(13)
            , _phrasesInUse = 0
            , _phrasesUsed  = 0
            , _joiner = ','
            , _result = ''
        ;
    
    
        ////////////////////////////////////////////////////
        // cosmetic adjustments
        if( eons > 999999 ) { _joiner = ';'; }
        if( secs > 0 || mins > 0 ) { _msecsPhrase = _nsecsPhrase = ''; } 
        ////////////////////////////////////////////////////
    
        _phrasePart[  0 ] = _eonsPhrase;
        _phrasePart[  1 ] = _gyearsPhrase;
        _phrasePart[  2 ] = _epochsPhrase;
        _phrasePart[  3 ] = _millsPhrase;
        _phrasePart[  4 ] = _centsPhrase;
        _phrasePart[  5 ] = _yearsPhrase;
        _phrasePart[  6 ] = _monthsPhrase;
        _phrasePart[  7 ] = _daysPhrase;
        _phrasePart[  8 ] = _hoursPhrase;
        _phrasePart[  9 ] = _minsPhrase;
        _phrasePart[ 10 ] = _secsPhrase;
        _phrasePart[ 11 ] = _msecsPhrase;
        _phrasePart[ 12 ] = _nsecsPhrase;
    
        // count the phrase pieces to use
        for( var i = 0; i < _phrasePart.length; i++ ) {
            if( _phrasePart[ i ].length ) { _phrasesInUse++; }
        }
    
        // assemble the output
        for( var i = 0; i < _phrasePart.length; i++ ) {
            if( _phrasePart[ i ].length ) {
                _result += _phrasePart[ i ];
                _phrasesUsed++;
    
                // only for the last phrase
                if( _phrasesInUse - _phrasesUsed === 1 ) {
                    _result += ' and ';
                
                } else
                if( _phrasesInUse - _phrasesUsed > 0 ) {
                    _result += ( _joiner + ' ' );
                }
            }
        }
    
        return _result;
    };
    
    
    function addCommas(t) {
        t += ""; var x = t.split("."), x1 = x[0], x2 = x.length > 1 ? "." + x[1] : "";
        for (var r = /(\d+)(\d{3})/; r.test(x1); ) x1 = x1.replace(r, "$1,$2");
        return x1 + x2;
    };
    
    
    console.log( 'getTimeFromYears( .75 ) -> ' + getTimeFromYears( .75 ) ); // 9 months
    console.log( 'getTimeFromYears( 9/12 ) -> ' + getTimeFromYears( 9/12 ) ); // 9 months
    console.log( 'getTimeFromYears( 1/365.2425 ) -> ' + getTimeFromYears( 1/365.2425 ) ); // 1 day
    console.log( 'getTimeFromYears( 1/365.2425 * 14 ) -> ' + getTimeFromYears( 1/365.2425 * 14 ) ); // 14 days
    console.log( 'getTimeFromYears( 1/365.2425 / 24 ) -> ' + getTimeFromYears( 1/365.2425 / 24 ) ); // 1 hour
    console.log( 'getTimeFromYears( 1/365.2425 / 24 * 730.485 ) -> ' + getTimeFromYears( 1/365.2425 / 24 * 730.485 ) ); // 1 month
    console.log( 'getTimeFromYears( 1/365.2425 * 0.0000000000000115741 ) -> ' + getTimeFromYears( 1/365.2425 * 0.0000000000000115741 ) ); // 1 nanosecond
    console.log( 'getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 ) -> ' + getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 ) ); // 1 nanosecond
    console.log( 'getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 * 12000 ) -> ' + getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 * 12000 ) ); // 12,000 nanoseconds
    console.log( 'getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 * 1000000 ) -> ' + getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 * 1000000 ) ); // 1 millisecond
    console.log( 'getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 * 12345678 ) -> ' + getTimeFromYears( 1/365.2425 / 24 * 0.000000000000277778 * 12345678 ) ); // 12 milliseconds and 345,678 nanoseconds
    console.log( 'getTimeFromYears( 123456789 ) -> ' + getTimeFromYears( 123456789 ) ); // 123 epochs, 456 millenia, 7 centuries, 88 years, 11 months, 30 days, 10 hours, 29 minutes and 5 seconds
    console.log( 'getTimeFromYears( 9876543210 ) -> ' + getTimeFromYears( 9876543210 ) ); // 9 eons, 876 epochs, 543 millenia, 2 centuries, 10 years and 11 seconds
    console.log( 'getTimeFromYears( 2.2527397260273973 ) -> ' + getTimeFromYears( 2.2527397260273973 ) ); // 2 years, 3 months, 1 day and 57 seconds

提交回复
热议问题