Unity日历选择器ZCalendar免费下载,使用说明

Posted JacobKay

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity日历选择器ZCalendar免费下载,使用说明相关的知识,希望对你有一定的参考价值。

前言

因工作需要,又找不到合适的,学习成本又低的日历组件,自己封装一套,也提供给小伙伴们一同使用,如有任何可优化的地方,也烦请各位大佬友情提出,感恩的♥♥♥

效果展示:

安装方法:

1、【https://gitee.com/jacobkay/unity-calendar】中的下载链接,免费拉取代码或者直接下载zip

2、将ZCalendar文件夹直接拖入工程内

3、将Prefabs/Zcalendar拖入到canvas下,即可使用

可配置显示项:

 1、可自定义初始化时间

2、可控制显示前后月的日期显示

3、可控制显示农历日期

4、可做静态日历显示

5、尺寸自适应

6、可控制超出当前日期是否可以点击

7、如果做为弹窗使用,点击周围可隐藏控件

8、可选择时间范围

配置说明: 

  1. Awake2Init:true => 以当前时间初始化,false => 不初始化,可通过ZCalendar中的Init方法初始化;
  2. AutoFillDate:true => 自动补充前后月日期,false => 不显示前后月日期;
  3. IsUnexpiredTimeCanClick:true => 超出当前时间可点击,false => 超出当前时间不可点击;
  4. Lunar:true => 显示农历日期,false => 不显示农历日期;
  5. IsPopupCalendar:true => 运行时,点击周边或者点击日期可隐藏日历,如果默认为隐藏状态,可关闭子对象bak,本身有管理脚本,不可隐藏,false => 为长显示日历
  6. IsStaticCalendar:true => 为静态日期显示日历,不可操作,false => 可操作日历
  7. AutoSetItemSize:true => 日期显示部分可根据尺寸自适应显示,false => 不会自适应显示
  8. RangeCalendar:true => 可选择时间范围,false => 可选择单天日期

预制体说明:

Zcalendar:日历预制体,将此预制体拖到canvas下,即可使用

ZCalendarDayItem:日历中天的预制体,可对其进行扩展

        RangeImageBak:区间时间选择时,背景图

        IsOnImage:选中时,背景图

        Text:当前时间显示

        Lunar:农历 

注意:如果大佬们只是使用,没有优化想法,挂载的组件及布局不可修改,但可扩展添加需用组件

脚本说明:

1、ZCalendar.cs:程序入口,API接口

2、ZCalendarController:逻辑控制器

3、ZCalendarModel:日历模型

4、ZCalendarDayItem:日历中每一天的时间对象

API(ZCalendar中):

1、在切换月份或者年份时,可获取到每一个日期对象

public event Action<ZCalendarDayItem> UpdateDateEvent;

2、切换日期时,可获取到选择的某一天

public event Action<ZCalendarDayItem> ChoiceDayEvent;

3、监听区间时间选择,获取选择的时间对象

public event Action<ZCalendarDayItem, ZCalendarDayItem> RangeTimeEvent;

4、日历加载结束时

public event Action CompleteEvent;

5、手动获取当前选中的时间对象

public ZCalendarDayItem CrtTime  get; set; 

6、按照当前时间初始化

public void Init()

7、按照DateTime格式初始化

public void Init(DateTime dateTime)

8、按照string,YYYY-MM-DD格式初始化日历

public void Init(string dateTime)

9、显示日历

public void Show()

10、隐藏日历

public void Hide()

主要逻辑实现说明:

1、上个月

获取当月第一天是周几,通过枚举获取索引值

int GetLastMonthDays()

    string firstWeek = new DateTime(Year, Month, 1).DayOfWeek.ToString();
    return (int)Enum.Parse(typeof(DayOfWeek), firstWeek);

2、当月

切换日期时,从当月第一天开始,循环当月天数

3、下个月

六行七列,总共42天,减去上个月的天数和这个月的天数,剩下的就是下个月天数

void FillNextMonth()

    int nextMonthDays = 42 - (lastMonthEmptyDays + days);
    if (nextMonthDays != 0)
    
         if (zCalendarModel.autoFillDate)
         
             DateTime lastDay = monthFirstDay.AddDays(days);
             for (int i = 0; i < nextMonthDays; i++)
             
                  AddDayItem(lastDay.AddDays(i));
             
          
     

4、获取时间

通过DateTime中一系列接口获取修改后时间

public DateTime Add(TimeSpan value);
public DateTime AddDays(double value);
public DateTime AddHours(double value);
public DateTime AddMilliseconds(double value);
public DateTime AddMinutes(double value);
public DateTime AddMonths(int months);
public DateTime AddSeconds(double value);
public DateTime AddTicks(long value);
public DateTime AddYears(int value);

农历实现

将当前时间DateTime传入,使用ChineseLunisolarCalendar获取当前农历时间,具体脚本如下:

public System.Globalization.ChineseLunisolarCalendar cncld = new System.Globalization.ChineseLunisolarCalendar();
        /// <summary>
        /// 农历月
        /// </summary>
        public string[] lunarMonths =  "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" ;

        public string[] lunarDaysT =  "初", "十", "廿", "三" ;

        /// <summary>
        /// 农历日
        /// </summary>
        public string[] lunarDays =  "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" ;        
/// <summary>
        /// 显示农历日期
        /// </summary>
        /// <param name="time"></param>
        void SolarToLunar(DateTime dt)
        
            int year = cncld.GetYear(dt);
            int flag = cncld.GetLeapMonth(year);
            int month = cncld.GetMonth(dt);
            if (flag > 0)
            
                if (flag == month)
                
                    //闰月
                    month--;
                
                else if (month > flag)
                
                    month--;
                
            
            int day = cncld.GetDayOfMonth(dt);
            lunarTxt.text = (day == 1) ? GetLunarMonth(month) : GetLunarDay(day);
            //Debug.Log($"year-(month.ToString().Length == 1 ? "0" + month : month + "")-(day.ToString().Length == 1 ? "0" + day : day + "")");
        
        /// <summary>
        /// 获取农历月
        /// </summary>
        /// <param name="month"></param>
        /// <returns></returns>
        string GetLunarMonth(int month)
        
            if (month < 13 && month > 0)
            
                return $"lunarMonths[month - 1]月";
            
        
        /// <summary>
        /// 获取农历年
        /// </summary>
        /// <param name="day"></param>
        /// <returns></returns>
        string GetLunarDay(int day)
        
            if (day > 0 && day < 32)
            
                if (day != 20 && day != 30)
                
                    return string.Concat(lunarDaysT[(day - 1) / 10], lunarDays[(day - 1) % 10]);
                
                else
                
                    return string.Concat(lunarDays[(day - 1) / 10], lunarDaysT[1]);
                
            
        

最后附上控制器代码

/*
 * Created by JacobKay - 2022.08.24
 */
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ZCalendar

    public class ZCalendarController
    
        public int Year  set; get; 
        public int Month  set; get; 
        public int Day  set; get; 
        /// <summary>
        /// 当前是否在区间选择状态
        /// </summary>
        private bool isInRange = false;
        public bool IsInRange  get  return isInRange;  
        private string week;
        private DateTime now;
        private int days;
        /// <summary>
        /// 当前选中的位置
        /// </summary>
        public Vector3 pos;
        private int lastMonthDays;
        private int nextMonthDays;
        public ZCalendar zCalendar;
        public ZCalendarModel zCalendarModel;
        public DateTime nowTime = DateTime.Now;
        private int lastMonthEmptyDays;
        bool isShow = true;
        public bool isInit = false;
        /// <summary>
        /// 保存文字颜色
        /// </summary>
        public Color greyColor;

        public System.Globalization.ChineseLunisolarCalendar cncld = new System.Globalization.ChineseLunisolarCalendar();
        /// <summary>
        /// 农历月
        /// </summary>
        public string[] lunarMonths =  "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊" ;

        public string[] lunarDaysT =  "初", "十", "廿", "三" ;

        /// <summary>
        /// 农历日
        /// </summary>
        public string[] lunarDays =  "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" ;
        DateTime monthFirstDay;
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="date"></param>
        public void Init()
        
            zCalendarModel.zCalendarController = this;
            zCalendarModel.Init();
            if (zCalendarModel.isStaticCalendar) return;
            // 动态日历,可关闭
            if (zCalendarModel.isPopupCalendar)
            
                zCalendarModel.btnClose.onClick.AddListener(() =>
                
                    Hide();
                );
            
            zCalendarModel.btnLastYear.onClick.AddListener(LastYear);
            zCalendarModel.btnNextYear.onClick.AddListener(NextYear);
            zCalendarModel.btnLastMonth.onClick.AddListener(LastMonth);
            zCalendarModel.btnNextMonth.onClick.AddListener(NextMonth);
        

        /// <summary>
        /// 按照规定时间初始化日历
        /// </summary>
        public void InitDate(DateTime date)
        
            now = date;
            DestroyAllChildren();
            UpdateYear();
            UpdateMonth();
            UpdateDays();
            UpdateData();
            if (!isInit)
            
                isInit = true;
                zCalendar.DateComplete();
            
        
        void LastYear()
        
            now = now.AddYears(-1);
            DestroyAllChildren();
            UpdateYear();
            UpdateMonth();
            UpdateDays();
            UpdateData();
        
        void NextYear()
        
            now = now.AddYears(1);
            DestroyAllChildren();
            UpdateYear();
            UpdateMonth();
            UpdateDays();
            UpdateData();
        
        void LastMonth()
        
            now = now.AddMonths(-1);
            DestroyAllChildren();
            UpdateYear();
            UpdateMonth();
            UpdateDays();
            UpdateData();
        
        void NextMonth()
        
            now = now.AddMonths(1);
            DestroyAllChildren();
            UpdateYear();
            UpdateMonth();
            UpdateDays();
            UpdateData();
        

        List<ZCalendarDayItem> dayItemList = new List<ZCalendarDayItem>();

        /// <summary>
        /// 如果是区间日历,选择时间时,需要判断当前日期选择状态
        /// </summary>
        /// <returns></returns>
        public void ChangeRangeType(ZCalendarDayItem dayItem)
        
            isInRange = !isInRange;
            if (dayItemList.Count >= 2)
            
                dayItemList.Clear();
            
            if (dayItemList.Count == 0)
            
                dayItemList.Add(dayItem);
            
            else
            
                int compare = DateTime.Compare(dayItemList[0].dateTime, dayItem.dateTime);
                if (compare <= 0)
                
                    dayItemList.Add(dayItem);
                
                else
                
                    dayItemList.Insert(0, dayItem);
                
            
            if (!isInRange)
            
                zCalendar.RangeCalendar(dayItemList[0], dayItemList[1]);
            
        
        /// <summary>
        /// 显示日历
        /// </summary>
        public void Show()
        
            if (pos != null && !isShow)
            
                isShow = true;
                zCalendar.transform.localPosition = pos;
            
        
        /// <summary>
        /// 隐藏日历
        /// </summary>
        public void Hide()
        
            if (isShow && !isInRange)
            
                isShow = false;
                Debug.Log("hide");
                zCalendar.transform.localPosition = new Vector3(pos.x, 5000, pos.z);
            
        
        /// <summary>
        /// 查询年数据
        /// </summary>
        void UpdateYear()
        
            Year = now.Year;
        
        /// <summary>
        /// 查询月数据
        /// </summary>
        void UpdateMonth()
        
            Month = int.Parse(now.Month.ToString("00"));
        
        /// <summary>
        /// 返回要查询那天
        /// </summary>
        /// <returns></returns>
        void UpdateDays()
        
            days = DateTime.DaysInMonth(Year, Month);
            if (Day == 0)
            
                Day = now.Day;
            
            else if (Day > days)
            
                Day = days;
            
        
        /// <summary>
        /// 更新显示月份
        /// </summary>
        void UpdateData()
        
            zCalendarModel.SetTimeTxt(Year, Month);
            FillLastMonth();
            for (int i = 0; i < days; i++)
            
                AddDayItem(monthFirstDay.AddDays(i));
            
            FillNextMonth();
        
        /// <summary>
        /// 自动填充上个月内容
        /// </summary>
        void FillLastMonth()
        
            monthFirstDay = new DateTime(Year, Month, 1);
            lastMonthEmptyDays = GetLastMonthDays();
            if (zCalendarModel.autoFillDate)
            
                for (int i = lastMonthEmptyDays; i > 0; i--)
                
                    AddDayItem(monthFirstDay.AddDays(-i));
                
            
            else
            
                for (int i = 0; i < lastMonthEmptyDays; i++)
                
                    ZCalendarDayItem dayItem = zCalendarModel.Instantiate();
                    dayItem.zCalendarController = this;
                    dayItem.CloseClickAble();
                
            
        
        /// <summary>
        /// 添加下个月的时间
        /// </summary>
        void FillNextMonth()
        
            int nextMonthDays = 42 - (lastMonthEmptyDays + days);
            if (nextMonthDays != 0)
            
                if (zCalendarModel.autoFillDate)
                
                    DateTime lastDay = monthFirstDay.AddDays(days);
                    for (int i = 0; i < nextMonthDays; i++)
                    
                        AddDayItem(lastDay.AddDays(i));
                    
                
            
        
        /// <summary>
        /// 添加日期对象
        /// </summary>
        void AddDayItem(DateTime dateTime)
        
            ZCalendarDayItem dayItem = zCalendarModel.Instantiate();
            dayItem.zCalendarController = this;
            dayItem.Init(dateTime, Day);
            zCalendar.UpdateDate(dayItem);
            if (!isInRange && dayItemList.Count > 0)
            
                dayItem.IsRangeDayItem(dayItemList[0], dayItemList[1]);
            
        
        /// <summary>
        /// 判断上一个月有几天
        /// </summary>
        /// <returns></returns>
        int GetLastMonthDays()
        
            string firstWeek = new DateTime(Year, Month, 1).DayOfWeek.ToString();
            return (int)Enum.Parse(typeof(DayOfWeek), firstWeek);
        
        /// <summary>
        /// 删除所有内容
        /// </summary>
        void DestroyAllChildren()
        
            List<Transform> lst = new List<Transform>();
            int count = zCalendarModel.dayContent.childCount;
            for (int i = 0; i < count; i++)
            
                Transform child = zCalendarModel.dayContent.GetChild(i);
                lst.Add(child);
            
            for (int i = 0; i < lst.Count; i++)
            
                MonoBehaviour.Destroy(lst[i].gameObject);
            
        
    

如需完整插件 和 更多好用插件,烦请大佬到【JacobKay的博客_CSDN博客-领域博主】中查看

如有插件优化,或者更多好推荐,烦请大佬友情指出

感谢观看~~~~

JQuery日期范围选择器日历与可变周

我想在jquery中实现类似于imageenter image description here的每周日期范围选择器

我能看到的唯一一个实现是使用mobiscroll插件,它不是免费的,我更喜欢用jquery或javascript或任何免费工具来做到这一点。

任何人都有其他想法或解决方案如何使用任何其他datepicker实现这一点?

答案

您可以尝试使用范围选项和日期范围选择器,您需要在此处构建自定义范围,如此处所示...

$('#datepicker').daterangepicker({
    "showWeekNumbers": true,
    ranges: {
        'Today': [moment(), moment()],
       'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
        'Last 7 Days': [moment().subtract(6, 'days'), moment()],
        'Last 30 Days': [moment().subtract(29, 'days'), moment()],
        'This Month': [moment().startOf('month'), moment().endOf('month')],
        'Last Month': [moment().subtract(1, 'month').startOf('month'), 
        moment().subtract(1, 'month').endOf('month')]
    },
    "startDate": "12/26/2018",
    "endDate": "01/01/2019"
}, function(start, end, label) {
    //
});

欲了解更多信息,请访问Date Range Piker Examples

以上是关于Unity日历选择器ZCalendar免费下载,使用说明的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.net Core 中创建日历日期/选择器?

JQuery日期范围选择器日历与可变周

日期选择器日历被隐藏在下拉列表中

在输入字段 c# 中的 Unity 上显示从日历中选择的日期

钉钉小程序如何做出日历选择器的效果?

需要一个免费的 ASPX 日期选择器 [关闭]