Kotlin Firestore Timestamp Add Time - android

Is there a way to add time to a Timestamp formatted time without having to convert it multiple times?
val seconds: Long = Timestamp.now().seconds
val utcDT = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.UTC)
val withTwo: LocalDateTime = utcDT.plusHours(2)
val date: Date = Date.from(withTwo.toInstant(ZoneOffset.UTC))
val new = Timestamp(date)
Log.d("sirEgghead", "Timestamp: ${Timestamp.now().toDate()}")
Log.d("sirEgghead", "utcDT: $utcDT")
Log.d("sirEgghead", "addedTwo: $withTwo")
Log.d("sirEgghead", "date: ${date.time}")
Log.d("sirEgghead", "new: ${new.toDate()}")
This is the mess that I went through just to add two hours and return it to Timestamp format two hours in the future.
Timestamp: Wed May 18 21:53:12 EDT 2022
utcDT: 2022-05-19T01:53:12
addedTwo: 2022-05-19T03:53:12
date: 1652932392000
new: Wed May 18 23:53:12 EDT 2022
I do not want to use the local system time in case the time on the device is incorrect. The data is stored in Google Firestore.

Instead of creating a LocalDateTime instance, create an Instant instance and add 2 hours to it, using its plus method which takes TemporalUnits for addition.
val seconds: Long = Timestamp.now().seconds
val addedSeconds = Instant.ofEpochSecond(seconds).plus(2, ChronoUnit.HOURS).epochSecond
val newTimeStamp = Timestamp(addedSeconds, 0)

Related

how to get date without depending on systems date [duplicate]

This question already has answers here:
How to get current time from internet in android
(8 answers)
Closed 3 days ago.
i want to get the date and time without using the systems date
i am using android studio emulator changing emulators date.
ex: todays date is 2 Feb 2023 but i change my devices date to 26 Feb 2023. i still want it to display 2 Feb 2023 of todays date without depending on systems/device date
this is my code
var dateTime: String
val timeZone = TimeZone.getTimeZone("GMT+8")
val calendar = Calendar.getInstance(timeZone)
val simpleDateFormat = SimpleDateFormat("d MMM yyyy", Locale.US)
simpleDateFormat.setTimeZone(timeZone)
dateTime = simpleDateFormat.format(calendar.getTime()).toString()
but it still returns depending on the systems date
Yes, it is possible but you need to make a network call for it
https://worldtimeapi.org/api/timezone/Asia/Kolkata
it will give you JSON like this
{
"abbreviation": "IST",
"client_ip": "122.170.105.143",
"datetime": "2023-02-15T10:23:26.414176+05:30",
"day_of_week": 3,
"day_of_year": 46,
"dst": false,
"dst_from": null,
"dst_offset": 0,
"dst_until": null,
"raw_offset": 19800,
"timezone": "Asia/Kolkata",
"unixtime": 1676436806,
"utc_datetime": "2023-02-15T04:53:26.414176+00:00",
"utc_offset": "+05:30",
"week_number": 7
}
Once you have JSON in the response variable you can parse it like
var response; //it will contains response
var datetime = response.getString("datetime");
//if you want to parse it in readable format do it like this
val informat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS")
val outFormat = SimpleDateFormat("dd/MM/yyyy hh:mm:s a")
outputString = outFormat.format(informat.parse(datetime))
you may need to execute the network call in IO Thread you can use this
import in your gradle
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
//your code
CoroutineScope(Dispatchers.IO).launch {
var response =
JSONObject(URL("https://worldtimeapi.org/api/timezone/Asia/Kolkata").readText())
val datetime = response.getString("datetime")
val informat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS")
val outFormat = SimpleDateFormat("dd/MM/yyyy hh:mm:s a")
var outputString = outFormat.format(informat.parse(datetime))
binding.text.text = outputString
}

How to format string to date in Android

In my application I one string such as 2023-2-14 and I want convert this to 2023-02-14.
I write below codes:
val format = SimpleDateFormat("yyyy-MM-dd")
val date: Date = format.parse(startDateStr)
Log.e("dateLog",""+date)
But in logcat show me this : Wed Feb 15 00:00:00 GMT+03:30 2023
Why? I used this format : yyyy-MM-dd.
Why not used this format?
you are just parsing date, without a time, thus date object have set 00 for hour, day etc. now use format method for converting old String to new one
val formatAs = "yyyy-MM-dd"
var format = SimpleDateFormat(formatAs)
val date: Date = format.parse(startDateStr)
Log.e("dateLog","date:"+date)
String dateAsStringFormatted = format.format(date);
Log.e("dateLog","dateAsStringFormatted:"+dateAsStringFormatted)
some other answers in HERE

Displaying time from timestamp in Unix, UTC in Android Kotlin

I am working on a simple weather app and am trying to display time in the format "K:mm a" (eg. 6:30 AM). I am fetching a timestamp in Unix, UTC for the specified place a user searches for such as NYC. The timestamp looks something like 1624836905 and the time zone offset such as -14400. I have a function which adds the two up, converts it to milliseconds and should return the time in the format specified. The function is as follows:
fun dateTime(time: Int, zone: Int, format: String = "EEE, MMMM d K:mm a"): String {
return try {
val sdf = SimpleDateFormat(format)
val netDate = Date((time.plus(zone)).toLong() * 1000)
sdf.timeZone = TimeZone.getTimeZone("UTC")
sdf.format(netDate)
} catch (e: Exception) {
e.toString()
}
}
And I call it such as:
sunriseTextView.text = dateTime(result2.lookup<Int>("daily.sunrise")[0], timeZone, "K:mm a")
sunsetTextView.text = dateTime(result2.lookup<Int>("current.sunset")[0], timeZone, "K:mm a")
The expected output is the sunrise/sunset time such as 6:01 AM and 9:05 PM. I am also rendering the current time at the specified place also obtained from the API. As follows:
dateView.text = dateTime(result2.lookup<Int>("current.dt")[0], timeZone)
Which outputs the current date and time at the place in the format "EEE, MMMM d K:mm a" (eg. Mon June 28 8:23 AM).
The current time is always correct, however, there is a problem with the sunrise and sunset times. If I input NYC, for example, the sunrise is 7:35 PM and sunset 10:39 AM. The sunrise and sunset for Tokyo, on the other hand, appears correct at 4:27 AM and 7:00 PM.
Clearly I am missing something as I know the API data is correct. I am looking for any suggestions, however, I would appreciate one which does not have API restrictions such as kotlinx-datetime which requires API 26.
Since there's API Desugaring, you can use java.time with API versions below 26.
That means you don't have to rely on those outdated datetime classes, like java.util.Date and java.text.SimpleDateFormat.
Your fun can be rewritten like this:
fun dateTime(time: Int, zone: String, format: String = "EEE, MMMM d K:mm a"): String {
// parse the time zone
val zoneId = ZoneId.of(zone)
// create a moment in time from the given timestamp (in seconds!)
val instant = Instant.ofEpochSecond(time.toLong())
// define a formatter using the given pattern and a Locale
val formatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH)
// then make the moment in time consider the zone and return the formatted String
return instant.atZone(zoneId).format(formatter)
}
Here's some example use in a simple fun main():
fun main() {
val timestamp: Int = 1624836905 // your example epoch seconds
// try two different zones
val newYorkTime = dateTime(timestamp, "America/New_York")
val tokyoTime = dateTime(timestamp, "Asia/Tokyo")
// and print the results
println(newYorkTime)
println(tokyoTime)
}
Output of this example:
Sun, June 27 7:35 PM
Mon, June 28 8:35 AM
Please note that you could as well use an offset: Int instead of a zone: String if you simply want to provide an offset of hours from UTC. You would need to adjust two lines of this fun then:
fun dateTime(time: Int, offset: Int, format: String = "EEE, MMMM d K:mm a"): String {
// parse the time zone
val zoneOffset = ZoneOffset.ofHours(offset)
// create a moment in time from the given timestamp (in seconds!)
val instant = Instant.ofEpochSecond(time.toLong())
// define a formatter using the given pattern and a Locale
val formatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH)
// then make the moment in time consider the zone and return the formatted String
return instant.atOffset(zoneOffset).format(formatter)
}
Using that in a main like this
fun main() {
val timestamp: Int = 1624836905
val newYorkTime = dateTime(timestamp, -4)
val tokyoTime = dateTime(timestamp, 9)
println(newYorkTime)
println(tokyoTime)
}
will produce the very same output.
In addition, the Locale used in the DateTimeFormatter could as well be a function argument in case you want to support different languages (this affects the names of months and days of week).
I have a similar function in Python like this:
def time(self, unix_time, time_zone):
date = datetime.utcfromtimestamp(unix_time + time_zone)
return (datetime.strftime(date, '%I:%M %p'))
Which I call as follows:
WeatherApp.time_zone = self.weather_results['timezone_offset']
print(self.time_date(self.weather_results['current']['dt'], self.time_zone))
print('Sunrise: ' + self.time(self.weather_results['current']['sunrise'], self.time_zone))
print('Sunset: ' + self.time(self.weather_results['current']['sunset'], self.time_zone))
I am trying to get the same result in Kotlin. However comparing the outputs is as follows:
Location: Tokyo, Japan
Current time and date: Tue, June 29 06:53 PM (same in Python and Kotlin from Asia/Tokyo, 1624960598 1624961970
32400)
Sunrise: 04:27 AM (as outputted in Python from 32400, 1624908462)
Sunset: 07:00 PM (as outputted in Python from 32400, 1624960847)
Sunrise: 4:27 AM (as outputted in Kotlin from Asia/Tokyo, 1624908467)
Sunset: 7:00 PM (as outputted in Kotlin from Asia/Tokyo, 1624960846)
---
Location: New York, United States
Current time and date: Tue, June 29 6:02 AM (same in Python and Kotlin from America/New_York, 1624960973)
Sunrise: 05:27 AM (as outputted in Python from -14400, 1624958860)
Sunset: 08:31 PM (as outputted in Python from -14400, 1625013070)
Sunrise: 7:35 PM (as outputted in Kotlin from America/New_York, 1624923330)
Sunset: 10:39 AM (as outputted in Kotlin from America/New_York, 1624977548)
Comparing the timestamps shows that the data obtained from the API differs for some reason. I currently solved it by using a different API. I was using the One Call API by OpenWeather. I can't think of a reason why this is happening, however, by getting the timestamp from a different API the issue no longer persists.

Converting Time to another timezone

I have a simple code where i want to convert a certain given time to another time zone , in my case the time is local to UK , but i need to convert the time to another timezone if the user lives in different country , i have tried this simple code but it is not working for me , it is giving me random hour 04:00
any help would be appreciated guys
This is the code
var localTime = "16:00" // simulating time to Uk timezone
localtime.text = localTime
timeZone.setOnClickListener {
val localTimes = "16:00"
val timeFormatter = SimpleDateFormat("hh:mm", Locale.UK)
val timezone = TimeZone.getDefault() // get device timezone
timeFormatter.timeZone = timezone
val timeToFormat = timeFormatter.parse(localTimes)
val formattedTime = timeFormatter.format(timeToFormat)
localtime.text = formattedTime
}

Localized time with leading zero

Under my locale DateFormat.getTimeInstance(DateFormat.SHORT).format(...) gives me 8:28 AM. Is there any way to get localized time but with leading zero (that is, 08:28 AM in my case) - I mean without hardcoding pattern etc?
If you want to have 24H format time you can do something like this using kotlin extensions:
fun Long.formatTime(): String? {
val calendar = Calendar.getInstance()
calendar.time = Date(this)
val hour = calendar.get(Calendar.HOUR_OF_DAY)
val minute = calendar.get(Calendar.MINUTE)
return String.format("%02d:%02d", hour, minute)
}
EDITED
If you still did't find the solution
val dateFormat = SimpleDateFormat("hh:mm a", Locale.getDefault())
print(dateFormat.format(Date()))
This prints
08:24 AM

Categories

Resources