How to inform date-fns about the input date format? - date-format

I need to return all of my input dates in yyyy-MM-dd format. Some input dates are in German format (dd/MM/yyyy) while others are in US format (MM/dd/yyyy).
I expect/want the code below to return "1979-12-31" in both cases. Instead, the second console output reads "1979-31-12" which means date-fns didn't notice the input date was in German format. How can I tell it that it's in German format, other than by passing the German locale to it as below?
const dateUS = '12/31/1979';
console.log('result with dinput date in US format: ',
format(new Date(dateUS), 'yyyy-MM-dd')
);
import { deLocale } from 'date-fns/locale/de';
const dateDE = '31/12/1979';
console.log('result with input date in DE format: ',
format(new Date(dateDE), 'yyyy-MM-dd', {
locale: deLocale
})
);

Related

Showing only days in React Datepicker calendar

I am trying to use React Datepicker in my React application. I am following this document - https://reactdatepicker.com/
I need a date picker which will only show 31 days.
Here is the simple code from the react-datepicker documents.
<DatePicker selected={dayPicker} onChange={(date) => setDayPicker(date)} dateFormat="yyy/MM/dd" isClearable={true}
/>
It shows the full calendar. How can I customize the calendar ? Is it possible to remove the header from the calendar and replace it with a text "Days" ?
Following code will give you date picker for current year with only Month in header.
You just need to use renderCustomHeader property of DatePicker.
const year = 2022; // can be provided externally
const month = 2; // can be provided externally
const date = 24; // can be provided externally
const [startDate, setStartDate] = useState(new Date(year, month, date));
const minDate = new Date(year, month, 1);
const maxDate = new Date(year, month + 1 , 0);
const renderDayContents = (day, date) => {
if(date < minDate || date > maxDate){
return <span></span>;
}
return <span>{date.getDate()}</span>;
};
return (
<DatePicker
selected = {startDate}
minDate = {minDate}
maxDate = {maxDate}
onChange = {(date) => setStartDate(date)}
renderCustomHeader = {() => <div></div>}
renderDayContents = {renderDayContents}
dateFormat = "dd"
/>
);
This is how it will look:
Explaination:
We can create out customer header with the renderCustomHeader property of DatePicker.
This functions returns JSX (kind of html) which has empty div as we don't want to show anything in header.
Apart from renderCustomHeader property, we have set minDate and maxDate property of DatePicker to restrict it for current month.
You need to copy above code in a component where you are using DatePicker.
You can refer https://reactdatepicker.com/#example-custom-header to know more about custom header for DatePicker

How to convert timezone format in iOS?

I got timezone format like this  GMT+5:30.
TimeZone.current.abbreviation(), this will return string value like: //GMT+5:30
 
But I need to convert the above format to Asia/Kolkata
How to solve this issue?
Instead of calling:
TimeZone.current.abbreviation()
call:
TimeZone.current.identifier
In your case you will get Asia/Kolkata instead of GMT+5:30.
But let's assume you only have a string with a timezone abbreviation such as "GMT+5:30". You can't easily convert that to a specific timezone identifier because there can be more than one timezone at a given time offset.
Here's a little function that creates a timezone from the abbreviation string and then finds all matching timezone identifiers that have the same offset.
func matchingTimeZones(abbreviation: String) -> [TimeZone]? {
if let tz = TimeZone(abbreviation: tzstr) {
return TimeZone.knownTimeZoneIdentifiers.compactMap { TimeZone(identifier: $0) }.filter { $0.secondsFromGMT() == tz.secondsFromGMT() }
} else {
return nil
}
}
You can get the matching list for "GMT+5:30" with:
let matches = matchingTimeZones(abbreviation: "GMT+5:30")
If you print that result you will see one of them is "Asia/Calcutta" (in an English locale).

Relative date parsing

How to parse relative datetime in GO?
Example of relative dates:
today at 9:17 AM
yesterday at 9:58 PM
Saturday at 9:44 PM
Wednesday at 11:01 AM
So format is DAY (in the past) at TIME. I tried next example:
const longForm = "Monday at 3:04 PM"
t, _ := time.Parse(longForm, "Saturday at 3:50 PM")
fmt.Println(t)
demo
Time is parsed correctly, but day/date is ignored...
Expanding on my comment:
Just Monday without further date reference is meaningless in the eyes of the parser, so it is discarded. Which Monday? The parser is strict, not fuzzy. Assuming Monday refers to the current week is not something that such a parser can do. You will not to write your own more sophisticated parser for that.
So it would have to be along these lines - one function that converts a relative fuzzy day to a real date, and replaces that in the original expression, and another one that parses the whole thing:
const dateFormat = "2006-01-02"
const longForm = "2006-01-02 at 3:04 PM"
func parseFuzzyDate(fuzzyTime string) (time.Time, error) {
formattedTime, err := parseDayAndReplaceIt(fuzzyTime)
if err != nil {
return nil, err
}
return time.Parse(longForm, formattedTime)
}
and the second function gets the fuzzy time, finds the day, parses it and returns. I'm not going to implement it, just write in comments what should be done:
func parseDayAndReplaceIt(fuzzyTime string) (string, error) {
// 1. Extract the day
// 2. Parse weekday names to relative time
// 3. if it's not a weekday name, parse things like "tomorrow" "yesterday"
// 4. replace the day string in the original fuzzyTime with a formatted date that the parser can understand
// 5. return the formatted date
}
I tweaked something that I wrote a while back and consolidated it into this example code:
func lastDateOf(targetDay time.Weekday, timeOfDay time.Time) time.Time {
const oneDay = 24 * time.Hour
var dayIndex time.Duration
//dayIndex -= oneDay
for {
if time.Now().Add(dayIndex).Weekday() == targetDay {
y, m, d := time.Now().Add(dayIndex).Date()
return timeOfDay.AddDate(y, int(m)-1, d-1)
}
dayIndex -= oneDay
}
}
It returns the date, relative to now, of the previous targetDay, added to timeOfDay, assuming that timeOfDay consists of hours, minutes and seconds, and the zero time values for year, month and day it will give you a suitable answer.
It's not very flexible but I believe it suits your example reasonably well. Although it doesn't address relative terms like "tomorrow", "yesterday" or "next Saturday".
runnable version in the playground.
Custom parser:
func RelativeDateParse(s string) (time.Time, error) {
for n := 0; n < 7; n++ {
day := time.Now().AddDate(0, 0, -n)
dayName := day.Format("Monday")
switch n {
case 0:
dayName = "today"
case 1:
dayName = "yesterday"
}
s = strings.Replace(s, dayName + " at", day.Format("2006-01-02"), -1)
}
return time.Parse("2006-01-02 3:04 PM", s)
}
demo

How to convert DateTime into different timezones?

How to convert DateTime into different timezones?
The DateTime class has two methods .toLocal() and .toUtc().
But if I want to display time in another time zone. How can I do it?
Here is my solution for EST time zone but you can change it to any other
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
extension DateTimeExtension on DateTime {
static int _estToUtcDifference;
int _getESTtoUTCDifference() {
if (_estToUtcDifference == null) {
tz.initializeTimeZones();
final locationNY = tz.getLocation('America/New_York');
tz.TZDateTime nowNY = tz.TZDateTime.now(locationNY);
_estToUtcDifference = nowNY.timeZoneOffset.inHours;
}
return _estToUtcDifference;
}
DateTime toESTzone() {
DateTime result = this.toUtc(); // local time to UTC
result = result.add(Duration(hours: _getESTtoUTCDifference())); // convert UTC to EST
return result;
}
DateTime fromESTzone() {
DateTime result = this.subtract(Duration(hours: _getESTtoUTCDifference())); // convert EST to UTC
String dateTimeAsIso8601String = result.toIso8601String();
dateTimeAsIso8601String += dateTimeAsIso8601String.characters.last.equalsIgnoreCase('Z') ? '' : 'Z';
result = DateTime.parse(dateTimeAsIso8601String); // make isUtc to be true
result = result.toLocal(); // convert UTC to local time
return result;
}
}
DateTime doesn't contain timezone information therefore you can't create a DateTime in a specific timezone only the timezone of your system and UTC are available.
You can wrap the DateTime in a custom class and add timezone information to the wrapper. You also need a table of offsets for each timezone and then add/substract the offset from the UTC date.
I wrote a package for this. It's called Instant, and it can convert a DateTime in any given timezone worldwide. Take a detailed look at https://aditya-kishore.gitbook.io/instant/
The basic usage for converting a DateTime to a timezone is very simple:
//Assumes Instant is in your pubspec
import 'package:instant/instant.dart';
//Super Simple!
DateTime myDT = DateTime.now(); //Current DateTime
DateTime EastCoast = dateTimeToZone(zone: "EST", datetime: myDT); //DateTime in EST zone
return EastCoast;
This works with one line of code and minimal hassle.
You can use an external package, like: timezone.
See docs here: https://pub.dev/packages/timezone
Here's a sample code to get the time in Los Angeles (PST/PDT).
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tz;
DateTime _getPSTTime() {
tz.initializeTimeZones();
final DateTime now = DateTime.now();
final pacificTimeZone = tz.getLocation('America/Los_Angeles');
return tz.TZDateTime.from(now, pacificTimeZone);
}
import 'package:timezone/timezone.dart'
String locationLocal = await FlutterNativeTimezone.getLocalTimezone();
//Esta Função recebe uma data/hora e converte para data/hora local.
TZDateTime convertFireBaseToLocal(TZDateTime tzDateTime, String locationLocal) {
TZDateTime nowLocal = new TZDateTime.now(getLocation(locationLocal));
int difference = nowLocal.timeZoneOffset.inHours;
TZDateTime newTzDateTime;
newTzDateTime = tzDateTime.add(Duration(hours: difference));
return newTzDateTime;
}
I modified Boris answer to pretend as user is in EST, otherwise time is adjusted to UTC:
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
extension DateTimeExtension on DateTime {
static int? _estToUtcDifference;
int _getESTtoUTCDifference() {
if (_estToUtcDifference == null) {
tz.initializeTimeZones();
final locationNY = tz.getLocation('America/New_York');
tz.TZDateTime nowNY = tz.TZDateTime.now(locationNY);
_estToUtcDifference = nowNY.timeZoneOffset.inHours;
}
return _estToUtcDifference!;
}
DateTime toESTzone() {
DateTime result = toUtc(); // local time to UTC
result = result.add(Duration(hours: _getESTtoUTCDifference()));
// convert UTC to EST and remove ZULU as it is not UTC anymore.
String dateTimeAsIso8601String =
result.toIso8601String().replaceAll('Z', '');
result = DateTime.parse(dateTimeAsIso8601String);
return result;
}
DateTime fromESTzone() {
DateTime result = subtract(
Duration(hours: _getESTtoUTCDifference())); // convert EST to UTC
String dateTimeAsIso8601String = result.toIso8601String();
dateTimeAsIso8601String += dateTimeAsIso8601String.endsWith('Z') ? '' : 'Z';
result = DateTime.parse(dateTimeAsIso8601String); // make isUtc to be true
result = result.toLocal(); // convert UTC to local time
return result;
}
}
Convert To IST for example, if not interested to use any non-verified lib in production.
DateTime.now().toUtc().add(const Duration(hours: 5, minutes: 30));
use simple EPOC time istead of other stuff
var now = DateTime.now().millisecondsSinceEpoch;
You can use TimeZoneInfo.ConvertTime() to change timezone. Try like this
DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try {
TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException) {
Console.WriteLine("Timezone not found");
}
catch (InvalidTimeZoneException) {
Console.WriteLine("Invalid Timezone");
}
This will convert from Hawaiian Standard Time to Local.
It is just an example. Use it to convert as per your need.

String format for currency(negative value formatted with braces)

When we convert like String.Format("{0:C}", 126.45) it returns $126.45
but if we convert like String.Format("{0:C}", -126.45) it returns ($126.45)
Why negative conversion return braces?
What to do if we don't want this braces?
Why don't you try something like:
String.Format("{0:$#,##0.00}", -126.45)
According to the documentation here a format of "{0:C1}" or "{0:C2}" should work, but for some strange reason it is not..
Another approach could be setting the CultureInfo:
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.NumberFormat.CurrencyNegativePattern = 1;
string s = string.Format(culture, "{0:c}", -126.45);
Reference here
Swift 5 Here is best solution if you get after formate this kind of value (-300)
extension Double {
static let twoFractionDigits: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
formatter.currencySymbol = "$"
formatter.currencyCode = "USD"
formatter.numberStyle = .currency
formatter.usesGroupingSeparator = true
return formatter
}()
var formatted: String {
return Double.twoFractionDigits.string(for: self) ?? ""
}
}
In the en-US locale, parentheses are used to denote negative values. Visually scanning a long column of numbers, many people find it easier to see the negatives. Often it's the negative values that are of most concern (oops! my checking account balance is overdrawn).
To get different formatting behavior, you can change your locale, or you can change your format specifier to something like F.
It does parentheses, because that's the standard on whatever CultureInfo you are using.
Never done it myself but the make up of the format is controlled by the current NumberFormatInfo instance.
If you figure it out, answer your own question, and I'll plus you

Resources