import React, { useState, useEffect } from 'react'; import { View, Text, TouchableOpacity, Dimensions, Image, TextInput, FlatList, Modal } from 'react-native'; const win = Dimensions.get('window'); const nDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; type IAdata = { value: any, type?: string, minDate?: any, maxDate?: any, visible?: boolean, onSelect?: (arg?: any) => void, onCancel?: () => void, theme?: string, months?: any, monthsShort?: any, weekDays?: any, weekDaysShort?: any } const DateTimePickerLib : React.FC = ({ value = "", type = "datetime", minDate = "", maxDate = "", visible = false, onSelect, onCancel, theme = "light", months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], monthsShort = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], weekDays = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], weekDaysShort = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"] }) => { const [activeDate, setActiveDate] = useState(value?new Date(value):new Date()); const [selectYear, setSelectYear] = useState(false); const [yearData, setYearData] = useState([]); const [date, setDate] = useState(value?new Date(value):new Date()); const [hour, setHour] = useState(value?("0" + new Date(value).getHours()).substr(-2):("0" + new Date().getHours()).substr(-2)); const [minute, setMInute] = useState(value?("0" + new Date(value).getMinutes()).substr(-2):("0" + new Date().getMinutes()).substr(-2)); let [initialIndexYear, setIndexInitialYear] = useState(0); useEffect(()=>{ let yearDatas:any = []; let minYear = minDate?Number(new Date(minDate).getFullYear()):1900; let maxYear = maxDate?Number(new Date(maxDate).getFullYear()):2101; for(let i=minYear; i<=maxYear; i++){ yearDatas.push(i) } setYearData(yearDatas) }, []) const generateMatrix = () => { let matrix:any = []; // Create header matrix[0] = weekDaysShort; let year = activeDate.getFullYear(); let month = activeDate.getMonth(); let firstDay = new Date(year, month, 1).getDay(); let maxDays = nDays[month]; if (month == 1) { // February if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { maxDays += 1; } } let counter = 1; for (let row = 1; row < 7; row++) { matrix[row] = []; for (let col = 0; col < 7; col++) { matrix[row][col] = -1; if (row == 1 && col >= firstDay) { // Fill in rows only after the first day of the month matrix[row][col] = counter++; } else if (row > 1 && counter <= maxDays) { // Fill in rows only if the counter's not greater than // the number of days in the month matrix[row][col] = counter++; } } } return matrix; } const _onPress = (item:any) => { let d = activeDate; d.setDate(item); setActiveDate(new Date(d)); setDate(d); }; const changeMonth = (n:any) => { let d = activeDate; d.setMonth(d.getMonth() + n); setActiveDate(new Date(d)); } function prevMonth() { let onDate = new Date(activeDate.getFullYear()+'-'+("0" + (activeDate.getMonth() + 1)).slice(-2)+'-'+("0" + activeDate.getDate()).slice(-2)); let _minDate = new Date(minDate); if(Number(onDate.getFullYear()) <= Number(_minDate.getFullYear())){ if(onDate.getMonth() > _minDate.getMonth()) { return renderPrevMonthButton(); }else{ return } }else{ return renderPrevMonthButton() } } function renderPrevMonthButton() { let d = activeDate; let monthName = ''; if(d.getMonth()===0){ monthName = monthsShort[11]; }else{ let res = d.getMonth() - 1; monthName = monthsShort[res]; } return( changeMonth(-1)} disabled={selectYear} > {monthName} ) } function nextMonth() { let onDate = new Date(activeDate.getFullYear()+'-'+("0" + (activeDate.getMonth() + 1)).slice(-2)+'-'+("0" + activeDate.getDate()).slice(-2)); let _maxDate = new Date(maxDate); if(Number(onDate.getFullYear()) >= Number(_maxDate.getFullYear())){ if(onDate.getMonth() < _maxDate.getMonth()) { return renderNextMonthButton(); }else{ return } }else{ return renderNextMonthButton() } } function renderNextMonthButton() { let d = activeDate; let monthName = ''; if(d.getMonth()===11){ monthName = monthsShort[0]; }else{ let res = d.getMonth() + 1; monthName = monthsShort[res]; } return( changeMonth(+1)} disabled={selectYear} > {monthName} ) } const changeYear = () => { setSelectYear(!selectYear); } useEffect(()=>{ if(selectYear){ let index = yearData.findIndex(x => x===activeDate.getFullYear()); setIndexInitialYear(index); } }, [selectYear]) return( {prevMonth()} {months[activeDate.getMonth()]} changeYear()}> {activeDate.getFullYear()} {nextMonth()} { selectYear?( renderSelectYear() ):( {renderCalendarData()} { type==='datetime'?( Set Time Hour { let num = parseInt(text); setHour(num>24?'24':text) }} keyboardType="numeric" maxLength={2} /> : Min { let num = parseInt(text); setMInute(num>59?'59':text) }} keyboardType="numeric" maxLength={2} /> ):null } {weekDays[date.getDay()]}, {date.getDate()} {months[date.getMonth()]} {date.getFullYear()} {type==='datetime'?hour+':':''}{type==='datetime'?minute:''} { let newDate = date; newDate.setHours(Number(hour)); newDate.setMinutes(Number(minute)); newDate.setSeconds(Number('00')); newDate.setMilliseconds(Number('000')); onSelect ? onSelect(newDate) : false }} > SELECT CANCEL ) } ) function renderSelectYear() { return( { return( { let d = activeDate; d.setFullYear(item); setActiveDate(new Date(d)); setSelectYear(false); }} > {item} ) }} initialNumToRender={yearData.length} initialScrollIndex={initialIndexYear} onScrollToIndexFailed={()=>{}} keyExtractor={(item, index) => index+''} /> ) } function renderCalendarData() { let matrix = generateMatrix(); let rows:any = []; rows = matrix.map((row:any, rowIndex:number) => { let rowItems = row.map((item:any, colIndex:number) => { let active = false; if(item === date.getDate() && activeDate.getMonth() === date.getMonth() && activeDate.getFullYear() === date.getFullYear()) { active = true; } if(rowIndex===0){ return ( {item != -1 ? item : ''} ) }else{ return ( _onPress(item)} disabled={item != -1 && disableDate(item)} > {item != -1 ? item : ''} ) } }); return ( {rowItems} ); }); return rows; } function disableDate(date:any) { if(minDate || maxDate){ let monthDate = new Date(activeDate.getFullYear()+'-'+("0" + (activeDate.getMonth() + 1)).slice(-2)+'-'+("0" + activeDate.getDate()).slice(-2)); let onDate = new Date(monthDate.setDate(date)); let _minDate = new Date(minDate); let _maxDate = new Date(maxDate); _maxDate.setDate(_maxDate.getDate() + 1); if(onDate.getTime() < _minDate.getTime() || onDate.getTime() >= _maxDate.getTime()){ // set not active date return true; }else{ return false; } }else{ return false } } } export default DateTimePickerLib;