Calculate datetime between client and server (Node JS) - node.js

I have an application that uses subscriptions for each member that joins. I'm having some issues with dates and calculations related with it. For example, let say a member joins on 2/10/2020 at 10:00. When the user submit the request to the server to process the subscription (the server is using UTC) the date that is being calculate is 2/10/2020 16:00 (because I'm -6:00 hours from UTC). This scenario is OK at this point, because the date is still the same (no matter the time). But, if we replicate this scenario when the user joins for example 2/10/2020 at 19:00, when the request is received and calculate the date, the result is 2/11/2020 01:00, and that produces an error in the invoice because the billing date of the invoice is wrong (one day after). What is the best way to implement this? I have read a lot of this topic, but most of the pages and questions are related in the other way, server to client, to parse of format dates to display to the user.
I have several questions related with this process.
Should I sent the date for the UI to the API? Or the timezone and
based on that, calculate the date in the API? (since the server have
UTC)
Moment.js library have a way to solve this or should be better with vanilla Javascript using Date?
Is there any HTTP header for the request to handle the time or date?

This really depends on what behavior you want to have. Before you try to fix anything, think through and decide on the exact requirements for what the billing date should be based on.
Is the user's time zone relevant? If so, you'll likely need to know what the user's time zone is. You'll be potentially assigning different dates to different invoices even if they're using the same UTC point in time. Your business might get confused on why some customers have invoice dates before or after the business day.
Or maybe the time zone of your company is more relevant? Many business work that way. All of your invoices will be aligned, but some customers might get confused on why their invoice date is before or after their current date.
Or maybe some customers snap to time zones of nearby offices, in the case of businesses with offices around the world.
Only you and your company can decide this. There are probably other options I'm not thinking through here. It's a business decision, not a technical one.
On your three questions:
That depends on what you decide above.
Libraries are a good idea for simplifying your code, but they're not a hard requirement. You can use the Date API, if you know what you're doing, but you may find libraries easier to work with. Also, Moment is in maintainance mode. For new development, the Moment team recommends you use Luxon instead of Moment. There are other popular modern libraries also, including date-fns and js-Joda.
There's the date header, but that's not going to help you with this.

Related

Additional packages to use with NodaTime

I am updating an application to use NodaTime to fix many existing time issues with our data and processes.
I will need to resolve timezones from a mobile app that sends IANA timezone names. I will need to support conversions to UTC using custom offsets (i.e. hard coded -04:00). I may or may not need to support Windows timezone names as well.
For all of this, I am wondering if I need additional packages. How do TimeZoneConverter and TimeZoneNames work alongside NodaTime? Are there any other additional packages I should use alongside NodaTime?
Our ultimate goal is to get all data persisted as Utc and convert to/from user time only for display or accepting user input.
You don't need any extra packages for that scenario, as far as I can see.
For IANA IDs, just use DateTimeZoneProviders.Tzdb
For "raw offset" IDs, you can use any time zone provider, asking for an ID of the form "UTC+01:00" etc. (So you'd need to add the "UTC" prefix.)
For Windows zone mapping, you can use TzdbDateTimeZoneSource.Default to get the default TZDB information, then use the WindowsMapping property to get a WindowsZones object you can use for mapping.
TimeZoneConverter may well be simpler to use for the last bullet point, but it's not required. The IANA IDs it provides should work fine with Noda Time.
TimeZoneNames is more about displaying time zone names to users. If you don't need to do that, you probably don't need the package.
Note that persisting all data as UTC may be a really bad idea - it's hard to tell without knowing more about your application. If you only deal with values in the past, or if they're fixed instants in time, that's fine. But if you're allowing users to schedule future events, I'd store the values that the user gave you. Here's an example of why...
Suppose the user says they want to schedule an event for Europe/Paris at 9am on December 1st 2021. If you convert that to UTC now, you'll end up with 2021-12-01T08:00Z, because the current time zone rules say that Paris will be at UTC+1 in December 2021.
However, it's entirely possible that between now and 2021, France will have changed its time zone rules to be on "permanent daylight time", i.e. UTC+2 all year round. At that point, your UTC value of 2021-12-01T08:00Z would correspond to 10am in Paris on the given date - contrary to what the user specified.
It's fine to convert to UTC as well so that you can create a totally ordered view of the data, so long as you retain enough information to perform that conversion again every time there's new time zone data.
As I say, that may not be an issue for you, but it's worth knowing that the "received wisdom" of "Always store everything in UTC" is really not good advice for all scenarios.

How to code - 'Date' comparison in Alloy?

I'm a beginner in Alloy. This is my first model using Alloy Analyzer. I'm now building a generic model for Travel in Alloy. In this model, a user (I use sig Request in this model) can make a request for 'accommodation' (includes 'hotel' or 'apartment' or 'hostel'); 'flight'; or 'tour', (the request can be either one of them or any combination of them, for example hotel and tour). Each of them is subset of 'resource'. For now, I stick the request for one destination only, and check-in & check-out date for accommodation as well as inbound-date & outbound-date for flight must be the same as begin-date & end-date for user request.
My questions as follows:
Firstly, in order to ensure check-in, check-out, inbound, and outbound date are the same as as begin-date & end-date for user request, all of them is mapped to beginning_of_journey and end_of_journey (please see the codes). Is this the correct way?
Secondly, I have a problem on how to code the constraint - tour date must be within begin-date and end-date of user request (so that the tour date must be within check-in, inbound, check-out, and outbound date as well). I define a set Date (sig Date) that has the fields day, month, and year where each of them has been defined as Integer. However, the problem is day can be negative number. And after executing the codes, the given instance seems weird. Could anyone please give a suggestion or advise me the right way to define that constraint?
Thirdly, I have a question that need to be clarified. Let say, the above problem has been resolved, and I need to initialise the specific request, for example tour date is July 1, 2016, date-begin is July 2, 2016 and end-date is July 4, 2016. Since I have defined the above constrained (Question No. 2), I want Alloy informs that the date given are violated. Is it possible to Alloy to do that?
I would really appreciate if anyone could give some comments and advice. Thank you
You need to test dates for sameness and for order. Unless you are trying to check the correctness of a design for calculating sameness and order of dates in the Gregorian calendar, however, there seems to be very little utility to modeling the internal structure of dates in Alloy.
So in your position I would, as Loïc Gammaitoni has already suggested, define an ordering on Date to support your queries on sequence.

How to properly model interest accumulation in an event sourced savings account application?

In my event sourced application developed using DDD, there are saving accounts that should accumulate interest every day. At the end of every year the accumulated interest should be capitalized. My question is: Should every daily calculation really be treated as a domain event?
An alternative could be to calculate the accumulated interest at a given point in time on the read side by traversing the transactions that has happened on the account up until that day (withdrawals, deposits etc), and sum the accumulated interest for each day.
The amount of events in the event store would quickly grow to millions, given that there could be hundreds of thousands saving accounts in the system calculating their accumulated interest each day. But at the same time it seems like a drawback to have to calculate the accumulated interest "on the fly" on the read side instead of raising an event every day.
I'm no banking expert, but InterestCredited looks like the event you really want to store since it will change the state of the system.
Accumulated interest is a virtual concept if I understand correctly - modelling it as an event of its own adds no value. You would be able to calculate the capitalized interest at the end of the year anyways regardless of daily InterestAccumulated events being present. Instead, a simple read-side value recalculated each day seems to match the need pretty well.
Interest accumulation is only a domain event when it gets credited/debited to an account. Until that occurs it doesn't mutate aggregate state. Consider corrective events, posting errors (e.g an NSF credit reversal). You would need to correct for every daily incorrect interest calculation between the original and correction.
The read side can take care of rolling up accrued interest at whatever intervals desired.
Should every daily calculation really be treated as a domain event?
What do your domain experts say?
You might also want to review chapter 11 of the blue book, which includes "Example: Earning Interest with Accounts". That may not directly answer your question about the domain events, but it should provide you with some extra context for framing your own analysis.
I'm not a domain expert, but my expectation would be that accrued interest has implications, either legal, or in the model, and that you would expect to have a consistent record of the accrual and its consequences on your model.
From your initial description, the impact on the model is annual, so I would expect to see the InterestCapitalized event only once per year per account. But I find it difficult to believe that daily accrued interest doesn't matter, especially in the face of changing balances and compounding interest, so I'm suspicious that the described requirement actually matches the needs of the business.
I wouldn't expect "millions" of events to be that big a problem; using the CQRS pattern, most of your reads are going to come out of rolled up results anyway, so that's not a big deal. The real hurt will be in trying to re-hydrate an aggregate with millions of events; but if you are facing performance problems there, you can look into loading the aggregate from snapshots.
And of course, if each account is calculating its own accrued interest, then you are only looking at 365 (ish) extra events per year, which is no sweat at all.

Writing a REST API for Complex Nested Data

So, I'm building an application in Angular which would leverage a REST API at the back, running on Node. I'm having some trouble handling the data complexity while designing this API and could use some help.
Here are the different resources, in question.
Doctors (each doctor may have multiple patients)
Patients (each patient may have multiple doctors)
Appointments (appointments exist for doctors, naturally)
Reminders (reminders may be sent from doctors to patients, not the other way around)
Now, here are some of the operations that the application may carry out, so the requirements from the API are clear.
Each doctor must be able to request for all his patients or a particular one.
Each patient must be able to request for all his doctors or a particular one.
Each doctor must be able to request for all his appointments (to see all patients) for a particular date, or for all days, if necessary.
Each patient must be able to request for all his appointments (to see all doctors) for a particular date, or for all days, if necessary.
Each doctor must be able to request for all appointments from a single patient.
Each patient must be able to request for all his appointments from a single doctor.
Each doctor must be able to request for all his reminders to a particular patient.
Remember, the request could naturally be a POST, GET, DELETE or PUT. Now, here is where I am so far. I'm only mentioning the URL, the operation on each when sent a POST, GET, DELETE or PUT is self-explanatory.
/doctors/
/doctors/:id
/doctors/:id/patients (returns a list of /patient/:id)
/doctors/:id/appointments
/patients/
/patients/:id
/patients/:id/doctors (returns a list of /doctors/:id)
/patients/:id/appointments
Now, I'm okay with the ones above. Here are my questions.
How do I design a URL for task number 7 without having nesting like /doctors/:id/patients/:id/appointments?
Also, I can get all appointments for a doctor or for a patient quite easily with the above. What about particular appointments? /doctors/:id/appointments/:id or /patients/:id/appointments/:id doesn't feel quite right.
Also, what about appointments to see a particular patient or a particular doctor?
And what about appointments for each doctor or patient on a particular date?
I feel like too much nesting is going on. Please help.
Your list of endpoints looks good. I guess there can be different opinions about what you asked.
The following are my opinions about what could be done:
How do I design a URL for task number 7 without having nesting like /doctors/:id/patients/:id/appointments?
I would suppose a collection of reminders would exist and define it as follows:
/doctors/:doctorid/reminders
/doctors/:doctorid/reminders/:patientid
Also, I can get all appointments for a doctor or for a patient quite easily with the above. What about particular appointments?
/doctors/:id/appointments/:id or /patients/:id/appointments/:id
doesn't feel quite right.
There is no need to complicate the endpoints to that level. If you already know the appointment id why would you reach it through the doctors or patients endpoints? It does not not matter, you reach the item directly through its collection.
/appointments/:appointmentid
Also, what about appointments to see a particular patient or a particular doctor?
You can leverage the power of query parameters for this kind of thing. Not everything has be part of the URL template. Features like filtering of specific records could be added to the query parameters instead. For instance
/doctors/:doctorid/appointments?pantientName=
/patients/:patientid/appointments?doctorName=
And what about appointments for each doctor or patient on a particular date?
Same thing here, you could something like:
/patients/:patientid/appointments?from=&to
Or have special endpoints for very well know cases like, my appointments for today, for this week, for this month:
/patients/:patientid/appointments/:year
/patients/:patientid/appointments/:year/:month
/patients/:patientid/appointments/:year/:month/:day
These latter could actually reuse the same logic used to implement the one getting appointments between a range of dates.
The URI structure is not a REST concern, because according to the uniform interface constraint it has to be decoupled from the client.
What matters:
A specific URI (including the path and the query) can identify only a single resource.
The URI is mapped to the resources and not to the operations, so if you use human readable nice URIs, then they will contain only nouns.
How do I design a URL for task number 7 without having nesting like
/doctors/:id/patients/:id/appointments?
You can map reduce the existing appointment collection, like so:
/appointments?doctor=1&patient=1
/appointments/doctor:1/patient:1
And what about appointments for each doctor or patient on a particular
date?
You can use a date filter to do that:
/appointments?date=2014-09-02
/appointments/date:2014-09-02

Developing Online multiplayer management game

I wish to create a college project on a simple online multiplayer management game which will involve players setting orders for the day/week and then obtaining profits. Being a relative beginner I am unable to figure out the architecture required for this task.
As far as I am concerned I would be needing the following things:
A text interface to display the status of ongoing events and to set orders in a web browser.
A certain application that would calculate the results every minute and update the database.
A database
Sorry for being so newbish, but any advice or links or books on how to proceed will do.
Please comment if any more information is required.
Any programming language would be fine. Pick a lang / arch you or someone in your group are familiar with. I'm mostly a PHP/ZF, Linux, Postgres guy. So I would...
Write a little ZendFramework app to collect your user's data and save to postgres database. I'd host it on a little Linux server. I like slicehost.com $20/mon, but there are cheaper. Or make friends with someone with a server.
Then for the update of the orders, use a cron job to run every minute. If the update process is complex, use another PHP script, else just straight SQL.
Why do you need to run updates every minute? Are people going to be updating it that often, if they are making orders for a day or week?
I would start with deciding on the equations that will be used in your model.
Then, that will help decide what you need in the database, to give the parameters to the model.
Then, once you have the database, you need to get information from the user, so decide what you need from the user.
For example you should have some random event that will make certain items go up or down in demand, or have resources become more common.
So, you may want to have information in the database that lists what each product is composed of.
If the model will have external information, or, if it is based on what others make, so, for example, last week shoes were not produced, so those that made shoes made a profit. This week everyone is making shoes, so there is too many, so the price went down.
This is why I think starting with your model, and testing your assumptions is the first step.
Any language, system, database will work well, just do what you feel comfy with. When you design the UI, do you want it to look fine on iphones and the Blackberry Razor? Then that will have a big impact on how you design the UI.

Resources