【问题标题】:How to get the meridian (am / pm) with momentsjs and angularjs如何用moment js和angularjs获取子午线(上午/下午)
【发布时间】:2015-12-24 12:03:06
【问题描述】:

我有一个关于库 moment.js 的问题,我有一个 angularjs 应用程序,其中我有六个选择元素,用于年、月、日、小时、分钟和 am/pm 格式。我正在使用以下格式时刻来构建 m.format date ('YYYY-MM-DD hh: mm: ss a)。

代码如下:

var m = moment([scope.val.year, scope.val.month, scope.val.date, scope.val.hour, scope.val.minute]); //build date 

model.$setViewValue(m.format('YYYY-MM-DD hh:mm:ss a'))

我得到了m.hour ()m.minute () 等数据,但是有一种方法可以获取 am/pm 格式,我没有找到任何关于它的信息,可能是 m.meridian () => "am "or" pm "

如果是上午或下午,我会构建作为参数传递的数组,如果是上午或下午,我也会从任何日期获取。

【问题讨论】:

  • 查看 moment 格式的文档...就在那里
  • @charlietfl - 实际上,不是。
  • @MattJohnson 确定是Aa ... momentjs.com/docs/#/displaying
  • @charlietfl - 是的,但语言环境会影响这一点。如果(例如)moment.locale() == 'zh-cn'moment().format("a") == "pm" 将失败。

标签: angularjs date momentjs


【解决方案1】:

您可以使用以下功能扩展时刻,并以与设置和获取小时、日、分钟等相同的样式使用它。

moment.fn.meridiem = function(newMeridiem) {
  if (!newMeridiem) {
    return this.format('A'); // or `return this.hours() < 12 ? 'AM' : 'PM';`
  }
  if (newMeridiem.toUpperCase() === 'AM' && this.hours() > 12) {
    this.hours(this.hours() - 12);
  } else if (newMeridiem.toUpperCase() === 'PM' && this.hours() <= 12) {
    this.hours(this.hours() + 12);
  }
  return this;
}

console.log("Current:",moment().meridiem());

console.log("Set as am result:",moment().meridiem('am').meridiem());

console.log("Set as pm result:",moment().meridiem('pm').meridiem());
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"&gt;&lt;/script&gt;

复制自https://github.com/moment/moment/issues/3873

【讨论】:

    【解决方案2】:

    另一个答案很好。它帮助我创建了演示,因为如果没有它,我会错过月份(0 到 11)的要点。

    但是您不需要创建 meridiem 函数,因为它已经在 moment.js 中实现。关键是文档中的用法不是很清楚。

    您可以像这样使用meridiem 函数:

    var curDate = moment().hour(yourHour); // create a moment date with the hour you'd like to test
    var meridiem = curDate
                .localeData().meridiem(hour); // will return AM/PM String
    

    如果您需要布尔值而不是 AM/PM 字符串,您可以将 AM/PM 字符串传递给 curDate.localeData().isPM(meridiem)。这将返回 true 或 false。

    您不想在选择中显示 0 到 11 的月份点可以通过 displayLabel 函数修复,该函数将递增月份数组的每个值。然后你会让它显示为 1 到 12,但存储为 0 到 11。如果你正在编写一个可以更好地由 ngModel$parser / $formatter 函数处理的指令。

    请看下面的演示或jsfiddle

    angular.module('demoApp', [])
    	.filter('momentDate', MomentDateFilter)
    	.filter('momentUTC', MomentUTCFilter)
    	.controller('MainController', MainController);
    
    function MomentDateFilter() {
    	return function(input, format) {
            return moment(input).format(format);
        };
    }
    
    function MomentUTCFilter() {
    	return function(input, format) {
            return moment.utc(input).format(format);
        };
    }
    
    function MainController($scope, $log) {
        var vm = this,
            now = moment();
        
        vm.checkHour = checkHour;
        vm.dateSelect = dateSelection();
        vm.displayLabel = displayLabel;
        vm.now = now;
        vm.selected = {
            "day": 27,
            "month": 8,
            "year": 2015,
            "hour": 18,
            "meridiem": "PM",
            "minutes": 6,
            "seconds": 20
        };
        
        function dateSelection() {
            return { // generated on every page load for demo
               	// better store the generate object as json and load it
                day: createRange(1,31),
                month: createRange(0,11),
                year: createRange(1900, 2100),
                hour: createRange(0,24),
                minutes: createRange(0,59),
                seconds: createRange(0,59),
                meridiem: 'AM_PM'.split('_')
            };
    	}
        
        function displayLabel(key, value) {
        	if (key === 'month') {
            	value++; // increment month for correct month value 1 to 12
            }
            return value;
        }
        
        function checkHour(key, hour) { // updates meridiem (AM/PM)
            if (key === 'hour') {
                var curDate = moment().hour(hour);
                //console.log('check hour', hour, curDate.hour(), curDate.localeData());
                vm.selected.meridiem = curDate
                    .localeData().meridiem(hour);
                //console.log(curDate
                //    .localeData().isPM(vm.selected.meridiem));
            }
            //console.log('changed', key);
        }
        //console.log(this.dateSelect);
        function createRange(from, to) {
            var arr = [];
        	for(i=from; i<=to; i++) {
            	arr.push(i);
            }
            //console.log(arr);
            return arr;
        }
        
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.0/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <div ng-app="demoApp" ng-controller="MainController as mainCtrl" class="container-fluid">
        <form class="form-inline">
            <div ng-repeat="(key, array) in mainCtrl.dateSelect" class="form-group">
                <label>{{key}}</label><select class="form-control" ng-change="mainCtrl.checkHour(key, array[mainCtrl.selected[key]])" ng-model="mainCtrl.selected[key]" ng-options="value as mainCtrl.displayLabel(key, value) for value in mainCtrl.dateSelect[key]" ng-disabled="key === 'meridiem'">
                </select>
            </div>
        </form>
        selected: <pre>{{mainCtrl.selected|json}}</pre>
        raw date (unformatted, UTC): {{mainCtrl.selected | momentUTC}}<br/>
        date formatted (meridiem locale): {{mainCtrl.selected | momentUTC : 'LLLL' }}<br/> 
        
        
        now (momentjs) {{mainCtrl.now}}
    </div>

    【讨论】:

    • 感谢您的帮助,Matt 的解决方案和您的解决方案对我有用。
    【解决方案3】:

    你也可以做类似m.format('a')

    【讨论】:

      【解决方案4】:

      一些事情:

      • 您要查找的词是"meridiem",而不是"meridian"。这是一个拉丁词,意思是“中午”。是。是“ante meridiem”(中午之前)​​和 P.M.是“午后”(中午之后)。

      • .hours() 函数和传递给 moment 构造函数的输入数组都期望 24 小时制的小时数,从 0 到 23。没有接受或输出 12 的内置函数- 小时时钟值,或 meridiem (am/pm)。

      • moment 中的解析和格式化功能确实有 12 小时制小时(hhh)和 meridiem(Aa)的选项,但您不是在解析或在您的用例中进行格式化,因此使用起来会有些笨拙。特别是,它们基于 moment 的当前语言环境设置,因此如果语言环境未固定为特定语言,则测试字符串会出现问题。

      • 您可以使用这些简单的函数将 12 小时 + meridiem 转换为 24 小时,反之亦然。它们不是特定于时刻的,因此您也可以将它们与 Date 对象或其他地方一起使用。

        function hours12to24(h, pm) {
            return h == 12 ? pm ? 12 : 0 : pm ? h + 12 : h;
        }
        
        function hours24to12(h) {
            return {
                hour : (h + 11) % 12 + 1,
                pm : h >= 12
            }
        }
        

        要测试这些功能:

        function test() {
          for (var i = 0; i <= 23; i++) {
            var x = hours24to12(i);
            var h = hours12to24(x.hour, x.pm);
            console.log(i + " == " + x.hour + (x.pm ? " pm" : " am") + " == " + h);
          }
        }
        
      • 另外,调用.month()获取月份编号时要小心,结果是0-11,而不是1-12。构建输入数组时也是如此。您的下拉菜单需要使用 0-11,或者您需要相应地加减 1。

      【讨论】:

      • 谢谢,你的解决方案对我很有用。
      猜你喜欢
      • 2013-06-04
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      相关资源
      最近更新 更多