 Some announcement first, we have the bags, laptop bags available at the registration counter for 1200 rupees and the t-shirts for Picon India will be distributed at 1230 at the same place and for open space talks, there are two slots still available you can register in the main lobby and also there are, you can register for lightning talks as well. And yeah, today we have with us Indradhanush Gupta and the talk is avoiding common pitfalls of dead time from Avivabh's perspective. Hi, I am audible right at the back. Okay, thanks for coming up. So yeah, like he said it's about avoiding common pitfalls of dead time. So basically the stock is going to cover off the difficulties we generally face when we are working with dead time objects. So the target audience, beginners in Python. Why beginners? Because dead time to beginners is like an opaque ball like you cannot see inside it. You don't really understand what's going inside it and you're actually very scared of it. Like I was very scared of dead time when I was starting with Python web developers. You build a website, you need a dead time, right? Like it's one of those things like when we were young parents and teachers used to say like kahibi jao, you need maths, right? So it's like that, like in programming kahibi jao, you need dead time. And basically anyone else. So why the stock? Dead time is the values, right? Like I said, and again, like it's not obvious from the beginning, where could you go wrong, right? Like when you were starting to work with dead time, you don't really realize that you're actually making a mistake. You only come to understand that you are maybe making a mistake when you have some real data in your hands and then some guy is complaining, hey, like this is not working for me or what. And basically I'll be sharing my own experience. Like this is stuff that I just learned after failing myself, like where are things that could go wrong? Just about fixing those stuff. So dead time, right? That's the, it's shipped with the standard library in Python. Few terminology is before I begin, really. So naive versus aware. So naive, dead time is an object that doesn't really have a time zone info with it, right? Like time zone as in, in standard time, UTC, whatever. So let's just take a look. Like if you take out the first line over here, right? From dead time input, dead time. So if I print this naive dead time over here, you can see that it specifies right down to the micro second resolution, right? But it doesn't really give you an information as in like what time zone it is. It's exactly equivalent to like, say I call you up one fine morning and tell you, hey, it's 12 o'clock where I am. Now tell me where I am. It doesn't make sense, right? Like I could be anywhere. I could be in India. I could be in Australia. I could be in US. So basically you should always be attempting to use date times with time zone. Like if I call you up and tell you that, hey, it's 12 o'clock in IST. So you'd know that even if you're in the US, you can basically use the time zone conversion to find out like, okay, then what's the equivalent time in my, right? You can just like, if you need an aware time zone, aware date time object, like all you have to do is pass the time zone to it, right? I'll come back to it in a while. So if you take a look right at the right corner, it has a plus 00, right? Which indicates it's in UTC, okay? Date time storage in Postgres. So when we are building a website, right? You cannot really live without a database, okay? And my talk is basically centered around the web app, the difficulties you face when you're building out on your web app, okay? And in my demo, I'll be using Postgres. So, okay, so this is the Postgres shell of my demo app that I have created, okay? And in my demo app, all that I have is, I have a table, okay, this is not, yeah, okay. I have a table that is named access keys, okay? So what this basically does is, it's telling you what the current time zone is for Postgres itself, okay? So when I do show time zone, Postgres is telling you, Key Boss, I am configured to use UTC. Well, you can change this. Actually, before that, let's see this. So what I'm basically doing over here is, I'm just displaying the one of the datetime fields that I have in my database, okay? So if you just take a look, no need to look at all this gibberish. Like just take a look at the plus 00, right? And maybe if you want to look at the first column. So it's like 1735 at plus 00. Actually, let's do a little bit. Sorry about this. So what you can do as well is, you can tell Postgres, Key, dude, I'm living in India. I don't want to see datetime in UTC. Like that doesn't make any sense to me. So what you can basically do is you can configure Postgres to use any other datetime, any other time zone, my bad, okay? So what I'm configuring here is basically to use the Indian standard time zone, okay? And when I display all the created attributes, you can see that if you remember it was 17 something, right? 1700 hours. So it's 23 plus 530. So it's basically converted into IST. But important thing to note over here is Postgres is always going to store your data in UTC. I mean, that's the default standard, right? Like whatever time zone you are, it stores it into UTC. Whatever time zone you need, it will convert it into that time zone and return you that object, okay? Should I ever use a naive datetime object? Well, to be honest, no, never. Frankly, when you give someone a naive datetime object, it actually makes their life very difficult because they have no clue what moment in time you intended, right? So you guys must be knowing about epoch, right? How many know about epoch? Okay, so epoch is basically 1970 first-gen, 1970, okay? And datetimes are measured in seconds since that point of time. So we measure that, so we name it as epoch. And so any datetime is, sorry, okay? Any datetime is basically seconds since 1970 first-gen, okay? So any datetime await object is actually representing a specific moment in time, right? Doesn't matter if it's UTC, if it's an IST, if you have the time zone information available with it, you can basically derive a meaningful relationship out of it, okay? PyTZ, right? Like in one of the slides, you saw something called PyTZ.UTC. So PyTZ is a third-party library which is actually, I found out to be very handy. So there are many, more than a couple of actually third-party libraries. So PyTZ is something I found out to be very handy because, I'll show you. So even though I'm telling you to use an await datetime object, not always will you have a time zone aware object, right? Let's say you are taking input from a user. Now of course you don't expect a user to enter plus 05 colon 30, right? So you have, you'll maybe use their IP address or whatever, right? To determine the time zone. But you still have a naive datetime object. So at times, you will have to add time zone information to a naive datetime object, okay? So to do that, basically, okay? This is the naive datetime object that we have from one of the previous slides, right? Now this is IST. So what I'm basically creating is, I am creating a time zone instance so that I can add it to a naive datetime object. So basically all you have to do is IST. So in right here, right? You can see that I have a IST datetime object. All you have to do is do IST.localize and basically attach the naive datetime object. So what you are effectively doing is adding time zone information to a naive datetime object. So if you take a look at the output at the bottom of the screen, like just compare the one at the top and the one at the bottom. The time is still the same. That's what I said, right? Like if you don't have a time zone information, I cannot do any conversion. The best I can do is add a time zone. So if I still add UTC into this, it's going to be 00. Converting datetime to another time zone. Your users will be in India and you will be in UTC, right? So the problem over here is that you cannot show a guy living in the US, a time respective in India, right? It doesn't make any sense to them. So all you have to basically do over here is you have an await datetime object, right? All you can do is like do an as time zone and insert the time zone information. And what happens is you can convert the object into the relevant time zone. I'm running a bit short on time. I'll just skip a little. Do not use datetime replace. So one thing over here is why not use replace? So you can actually replace the time zone information in an object by directly calling the dot replace method. So let's take a look. I have a UTC object over here and basically I can do a UTC dot replace and TZ info is equal to IST, right? Now if you note over here like look at the right hand bottom screen. The offset says as 0, 5, 53. Now we know IST is 5, 30, right? Like isn't that incorrect or something? Well, not exactly. I'll tell you why. And the offset of course is 5 hours, 53 minutes, right? So let's time the, let's try the method that I showed. So what I'm doing over here is I have an intelligent datetime. I'm creating it using UTC now dot as time zone. So if you take a look at plus 5, 30. So you have plus 5, 30 at the end, right? So the problem over here is that back in the 1900s, the time offset from UTC was 5 hours and 53 minutes. But replace doesn't know about this, okay? So if you have a datetime object in 1900s, as time zone is going to apply the time offset to 5 hours and 53 minutes. And if you have a datetime object more recent like 2015, the offset is going to apply as 5, 30. So like in the 1945, if I'm correct, India was also using daylight saving time, okay? And so the offset over there will be plus 6, 30. So it's, so you don't know what time the user is going to give you, right? So you have to handle the use cases accordingly. There you go, like you have the UTC offset, right? So if I use an old date over here, just take a look at number 12 right here. Old date is something in 1900s, right? And when I convert it using as time zone, the offset is 553. Okay. So some examples from production, right? So if you take a look at this pic over here, basically what I've been talking for the last 15-20 minutes, right? Guy sitting in India, he uploads at 530. Your database should be storing it in UTC. Guy sitting in US at PST, he can read it at 5AM PST like, he's like, okay, this guy uploaded just now. Like if he's awake at 5AM, okay, this guy just uploaded that right now, right? So at UTC 530, the equivalent time if it is 530PM, if the time is 530PM in IST, in UTC it is 12PM and in PST basically UTC minus 7, that's 5AM. So now you know like why you should be always using UTC itself, right? Because it's a standard common point where everything comes and converts into UTC and anything that goes out, you can basically convert into respective formats. Freeze gun. So a lot of times you'll have to be testing code, right? Which is dependent on daytime objects. Now an example, let's say you have access tokens, right? Like in APIs we have access tokens which you want to expire, let's say, you want to expire access tokens older than 30 days, right? Now you need to write test for this. Obviously you can't run a test for 30 days, like start the test, wait for 30 days to pass and then try to call your method that deletes it and see that if it is actually deleting it or not, right? Not very feasible. So what you should be doing is you use freeze time. What it does is, so if you take a look, we can use it as a context manager and so basically what it does is patches onto the daytime library. So what it's doing is when you call daytime, but now it's printing 2010 011, right? First January of 2010. So what freeze time does for you is it overrides the default value of daytime.now. You can also use it as a decorator over methods, right? Like the same thing, right? And decorator over class as well. The example that I was talking about, right? Now I generally don't want to put in a lot of code into this, but this is something I couldn't really avoid. So what I'm basically doing is over here, I am taking my limit as I'm going back 30 days from today's date. Like if today is 4th of October, I'm going 30 days back and what I'm doing is I'm taking out all access key objects from the database that are older than 30 days, okay? And what I'm doing is basically marking them as expired. So now this is the method that you want to test, right? And how to write test for it? If you have a Django test case like this. Now I want to create an access key object that was created, let's say 30 days back, right? Like about 4th or 5th September, right? So what I do is I freeze time as 1st January of 2015. So what I do is, when I do objects.create, now Django has this utility, like daytime objects can be initialized as the current time. So the current time in your system right now is going to be 2015 1st January. You cannot escape it, like inside the 1st with block. So if you come to the 2nd with block, what I'm basically doing is I'm changing the time to 31st January, okay? So now what I can do is I can create, I call the same, create call again, right? And now the created at time is going to be 31st January. So basically at like in one test, I have 2 objects that were created apart, 30 days apart, right? And if you like run an assert equal on this, like I can check that there are 2 instances, right? And then what I'm doing is I'm basically calling the method that I've defined above, right? And so once it's done, all I'm asserting is if life keys are equal to 1, like what I'm doing is I'm just checking out if it actually did pass the test, right? And it would work. How much time do we have? Sorry? 18 minutes I have? Okay. Oh, that's a lot of time. Fine. So date time dot time delta. So these are some stuff that you should be generally using in a lot of places. Like let's say your user wants all records in the last 30 days, right? Now, this is very tricky. 1st January to 30th January is very easy. What about 15 July to 15th of, from 15 July to last 30 days, right? I don't even remember if June has 31 days or June has 30 days. Not do you need, not do I have to write the logic to parse out if it has 30 days or not to make matters worse across leap years, right? If I want to check in the last six months and 2014 and 2015, if one of them is a leap year, how do you do it? So you do it with time delta. What time delta is basically is basically it's a difference between two times in seconds. But the library basically gives you some added information on like what's the difference. So what I have here is basically a date object, which is 3rd October. And so if I go back, want to go back by two weeks, what I have to do is date minus time delta weeks of two. So what it does is so it's roughly the same, right? Like so this library handles the intricate details for you. So you should really be using time delta a lot more often. You can even go back in days and it also gives you resolution up to hours, minutes, seconds and write down to microseconds. But if I want to go back by years and months, right? That is not something that time delta provides you. So we have relative delta. And actually it's a third party library, date it is. So what it does for you is again I have another date object, right? So what you can see is all I am passing it here is, Key Boss take me back in time by two years and six months and it's going to do exactly that. Like it's going to handle if there's a leap here or not, if there was any whatever, if there was any odd difference in time, if there was a leap second or not, it's going to just handle it for you. A lot of times you will also be getting input from the user. Like the user is entering the time in the browser, right? And you don't really have a Python object at the browser level, correct? So when I have it as a string, now it gets very difficult to convert it into a datetime object. I mean it could be very error-prone. So what I use is datetutile.parcel. What it does for you is it handles all the different formats. So you can see here, right? Like I send it a string in 2015-11, it's going to return you a datetime object. But again, you didn't pass it any time zone, so it's not going to attach any time zone to it. If you pass it 2015, it's going to assume by default that you're talking about 1st January. I'm sorry, you're talking about the current date on your system, right? Like if today is 4th October, which it is actually. So if you just pass it 2015, it's going to add the date and month to it. Well, you can actually pass it time zone information as well. And you can also pass it different time zones. Just the same example in UTC. Okay, we've come back down. Have you done? I think, yeah, I'm done. So that's it. Questions? Sorry? Right? So parser? Sorry, if you... Will it? Okay, so I actually don't know what the output of 1 will be. But if you enter, let's say, hello, it's going to raise an exception, like invalid format. Yeah, so you have to handle that in your code, right? Exceptions are something you have to handle. Okay. So parser is basically for converting strings to datetime objects, not the other way round. If you want to convert datetime to string, you need to be using strf time, basically string format time. You can actually use strip time in case of parser as well. But over there, you'll have to enter the formats like %y, %m. But honestly, half the time, I'm confused if %m capital is for month or %m capital is for minutes. Again, very confusing. But parser handles it all for you. You want to throw an error if the guy enters 2015. I guess you'll have to do it yourself. It's a library feature, right? That's a good thing. So if you want to go around it, I guess you'll have to do... You'll have to check if it's only the year has been passed or not. Like you have to manually check if the... Correct. In Django, we use the datetime fields and we give a default value. There are two options we can give. One we can give default equal to datetime.now. Or we can give Django's utils timesout.now. And is there any... What is actually doing the difference between these two methods? Can you tell me about the second one? Timesout.now. Timesout.now. Yeah. So in Django.utils.timesout.now? Yes. I haven't actually used it. So what I do in datetime objects for Django is... Django gives you two args. Like you can pass auto now equal to true and you can pass auto now add equal to true. What it means is when you pass auto now equal to true, that is every time the object is updated or even created, it's going to update that field, right? So it's very useful for fields like updated add. So you don't have to manually enter, get the datetime.now and do an update. So what you can do is like you have updated add as a datetime object and you can pass created add equal to true. The other thing you have is, sorry, auto now equal to true. The other thing we have is auto now underscore add equal to true. When you do that, what happens is it will only put the current time when you are creating that instance. So it's, so you have very easily you have created add and updated add. In Django's time zone settings file, in settings.py, you have the settings, time zone settings. You give, there is options like giving the time zone address UTC and we give the same UTC equal to true. And when we give UTC and we are running a program and actually when we are using testing, we will get the time object as UTC, mostly. But for checking, we use the, to get our own time zone, we give Asia Kolkata instead of UTC. Come again? To get the time zone value of our current India, we give, replace the UTC with Asia Kolkata. Okay. But when we want our website to continue production, it is accessed through the countries and how Django is actually deciding time zone to use because time zone is given at the settings. So what you have is, so in your settings, when you define the time zone, that's the default time zone that Django is going to use until and unless you specify explicitly. So if you are fetching instance, created at instance from the DB, it's going, so if you've set the time zone setting as UTC, it's going to return in UTC. If you're given it as Asia Kolkata, it will return you it in Asia Kolkata. But internally, like for Postgres at least, it's always stored in UTC by default. Hi. This is Gaurav here. So I just want to know, like if in our database, so the value is stored in UTC, the date time. And in my website, I want to show that time. So I want to show that time on the current zone. So like if I'm in India, I want to show the same time to convert automatically in IST time and show to the some website or something. And if I'm in the US or in some other zone, the same database entry I want to show in the current zone. So how we can do that. Exactly. So you would know what time zone the user is in, right? Yeah, that is the thing I want to know. So you'd know, right? No. If I'm anywhere, I just want to know, there may be some function or there may be some method from where we can get the current time zone and then we can replace. From the current time zone. For that, you have to use like actually, this thing called GUIP, like you try to determine the current time zone and the user using their IP address and all. So that PYTZ is not doing that? No, PYTZ is in the Python level, right? So what PYTZ does is, you tell PYTZ, boss, this is my daytime object. This is my time zone. I want you to give this daytime object in this time zone. So I have 2015, 1st January. Okay. And I have a time zone IST. I want the equivalent of 2015, 1st January. Okay. So one question here. So if you have a client server application and you want to sync time between the client and the server, do you have any suggestions? So there are time servers to sync up with, right? So actually, I didn't get the complete question like, when you say sync, do you want the server to be like, just can you explain it better? Yeah, so what I'm trying to say is like, I have a client and server running at the same time, but they may be in different time zones. Okay. And basically I want to sync up like, when the client is running for whatever time duration it ran, the same time the server was also available. So we're basically mapping time sync between both of them. Okay. So is there a way to do that? I mean, you have any suggestions? Yeah, like it's actually what basically you have to do is like, the client is going to say that, my current time is this, what's your current time, right? And the server is going to tell me like, okay, you are at 2015 1st January, I am at 2015 2nd January. And the client being a client should be accepting what the server is saying like, it's always like, right, so server is right. So, okay, like update the time. So it's actually not related to date time. It's more like about TCP communications. Okay. Thank you. Thank you guys.