timezones with moment-timezone - javascript

I am checking the list of timezones using moment-timezone from moment.js
moment.tz.names()
is giving 583 item , the list is very detailed and very huge, how can I get the main timezones out of it so I create a drop down list?
it goes like this :
"Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa",
"Africa/Algiers", "Africa/Asmara", "Africa/Asmera", "Africa/Bamako",
"Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre",
"Africa/Brazzaville", "Africa/Bujumbura", "Africa/Cairo",
"Africa/Casablanca", "Africa/Ceuta", "Africa/Conakry", "Africa/Dakar",
"Africa/Dar_es_Salaam", "Africa/Djibouti", "Africa/Douala",
"Africa/El_Aaiun", "Africa/Freetown", "Africa/Gaborone",
"Africa/Harare", "Africa/Johannesburg", "Africa/Juba",
"Africa/Kampala", "Africa/Khartoum", "Africa/Kigali",
"Africa/Kinshasa", "Africa/Lagos", "Africa/Libreville", "Africa/Lome",
"Africa/Luanda", "Africa/Lubumbashi", "Africa/Lusaka",
"Africa/Malabo", "Africa/Maputo", "Africa/Maseru", "Africa/Mbabane",
"Africa/Mogadishu", "Africa/Monrovia", "Africa/Nairobi",
"Africa/Ndjamena", "Africa/Niamey", "Africa/Nouakchott",
"Africa/Ouagadougou", "Africa/Porto-Novo", "Africa/Sao_Tome",
"Africa/Timbuktu", "Africa/Tripoli", "Africa/Tunis",
"Africa/Windhoek", "America/Adak", "America/Anchorage",
"America/Anguilla", "America/Antigua", "America/Araguaina",
"America/Argentina/Buenos_Aires", "America/Argentina/Catamarca",
"America/Argentina/ComodRivadavia", "America/Argentina/Cordoba",
"America/Argentina/Jujuy", "America/Argentina/La_Rioja",
"America/Argentina/Mendoza", "America/Argentina/Rio_Gallegos",
"America/Argentina/Salta", "America/Argentina/San_Juan",
"America/Argentina/San_Luis", "America/Argentina/Tucuman",
"America/Argentina/Ushuaia", "America/Aruba", "America/Asuncion",
"America/Atikokan", "America/Atka", "America/Bahia",
"America/Bahia_Banderas", "America/Barbados", "America/Belem",
"America/Belize", "America/Blanc-Sablon", "America/Boa_Vista",
"America/Bogota", "America/Boise", "America/Buenos_Aires", ..........
thank you

I don't know of any such list. After all, who decides which time zones are the "main timezones"? However, one option is to do what Microsoft Windows does and sort the list by timezone offset:
From the moment docs:
moment("2016-03-03").tz("America/Toronto").format('Z');
will give you the offset of that particular zone, e.g., -05:00. You can get the offset for each zone, sort by offset, and then present the list. The text in the list can be the zone name, or the part after the /, with _ replaced with space (e.g., America/New_York -> New York).

As everyone has said, the list is the list. What I did to narrow down the list is use a session variable that has the user's timezone, and if that is null, then use a default of America/UK/South Africa/Australian timezones. For my company, this is where the majority of our customers come from. Not many Canadians, strangely enough.
This is all in PHP, and not JavaScript, but it shouldn't be too hard to read and figure out. What's important are the steps used to narrow down the results.
Here's the gist:
https://gist.github.com/NoMan2000/a262a96b159164882cd7
The output.html shows you what the default timeZone breakdown is.
The most important file is the CountryCodesAndAbbr.php file.
https://gist.github.com/NoMan2000/a262a96b159164882cd7#file-countrycodesandabbr-php
It has an array of five different country ISOs stored in JSON format. It makes a CURL request, responds with the JSON, and then stores that in a file so I don't have to keep re-downloading the files each time, and bombarding the APIs.
For our purposes, only worry about the getContinentAndCountry method, as that contains all the data we'll need. This is what moment does for you in javaScript, with some tweaks to how the API gets called.
The TimeFormatter is a class for dealing with how PHP internally handles timezones, and I need to translate between the user's country-code and the displayed timezones so I don't overwhelm them.
In PHP, I use the user's country that I get when they sign up, so I have a region to pass into the method to narrow down the results. If you don't have a session variable or some other information saved, use this API.
http://freegeoip.net
This will give you the country when you make a request to it with the user's IP. Now you have the country.
If you don't get a result back, then do what I do and default to the regions where you get the most customers, with an optional <select> field that will allow them to pick the country they want.
You have to pick whether or not you are going to use the IP or if you have some way of getting a value to the user.
Lastly, pass in the country to the TimeFormatter->getTimezonesByCountryCodeLookup(region)
https://gist.github.com/NoMan2000/a262a96b159164882cd7#file-timeformatter-php
That takes the 2 letter country code and looks it up. The end result is you end up with a much smaller result that user can navigate. I combined this with chosen.js and it enabled them to just type in their abbreviation to narrow it down.
You will have to adapt this code to your own uses, but hopefully it shows you how to go about doing it.

Related

Get changes based on uploaded time from firebase

I have initialized a real time database using firebase, I am detecting live changes to the databse using
const ref = firebase.database().ref("test");
ref.on('value', function(dataSnapshot){
console.log(dataSnapshot.val())
});
But this returns me value in ascending order. Whereas I want it to return based on time. I tried using time in: 00:00 (IST) format but if a data is marked 11:59 (am) and another 01:02 (pm) this will return me the second message first.
What will be the best way to fix this?
example data is =>
in my databse =>
It is not clear what you mean by time in ascending order
None of your example data mention time. They are just usernames and text.
If you want to order times correctly, best to use ISO date format
This stores 1:02 pm as 13:02, which will sort after 11:59. Its sorting characteristics are ideal.
Use an international time standard to store your times
An international time standard, UTC, has great advantages over national times. It is not subject to change with location, political decisions, or season. You can always interconvert with the user's local time, at the time of entry or display.
Example
const dateString = (new Date()).toISOString();
console.log(dateString)
// Result:
// 2021-06-22T14:40:37.985Z
// If you want to use them as Firebase keys, they must not contain a ".", so you might clean it up like this:
const cleanDateString = (new Date()).toISOString().replace(".","-")
console.log(cleanDateString)
// Result:
// 2021-06-22T14:47:44-445Z
Even better, use a Firebase PushID
The above date-and-time system will work if you are using it to sort the remarks made by a single person, but will not be good as a message identifier if a single space is shared by all people, since 2 people will eventually make a message at the same millisecond, and will get the same message ID.
To deal with that it is better practice to use a Firebase Push ID.
An explanation is given here: In Firebase when using push() How do I get the unique ID and store in my database
Or from Firebase itself, here:
https://firebase.google.com/docs/database/admin/save-data

How to input a number and output a random number, yet keep output the same if given the same ID on a different machine

Currently I"m working on a small script in scriptish which takes in a user ID (currently on our forums, we have userID from 1 to 63) and colors it with a random color using this following function:
function setNickColor(nick)
var spans = nick.getElementsByTagName('span');
var uid = nick.getAttribute('hovercard-id');
if (colors[uid] == null)
storeColor(uid, Math.random().toString(15).substring(2,8));
This gives me a random color generated in 24 bits(for rgb color) individually for each person that installed the script. I'd like to have each ID generate a fixed random color. I don't understand how to work the ID into the function so that it's still random yet generates a random color still.
I looked at seeds but it's a bit difficult to understand what they do because I'm very new to javascript
As I see it there are two main components of your solution:
Generate a random color for a userid.
Associate this random color with the userid on subsequent requests.
Since you've already done the first one, it leaves the second one. Here are some options depending on what kind of flexibility the back end system provides you:
You could write a webservice, call it from your javascript function. The payload for your call would be the userid and the generated color, which your webservice would store in the back end database. Your template would then check for each user if the color isn't set, generate a random one and set it (and refresh the page, for the initial setup).
You could set a cookie in the browser that represents the color you generated, then load this cookie and use it to alter the userid being displayed. The downside to this is that it is browser dependent (on the same machine, on two browsers, you could have two different colors for the same userid), and if the person clears their cookies the color will be regenerated.
The third option is what Oleg suggested - create some hash of the userid (its a one-way algorithm so you are guaranteed the same result given the same input), and then take a component of this hash as the basis of your color. The benefits are you avoid the cookie and the webservice problem; but the challenges are you need to make your color generator a bit more "random" as it may be you end up with colors that aren't that visually distinct.
"Fixed" and "random" are two very opposite things. Forget random. According to your description you really just want "fixed".
Now for solution: take an arbitrary hash of ID and then reduce it to just 3 bytes to form RGB value that'd correspond to that ID.

Javascript function taking too long to complete?

Below is a snipet of code that I am having trouble with. The purpose is to check duplicate entries in the database and return "h" with a boolean if true or false. For testing purposes I am returning a true boolean for "h" but by the time the alert(duplicate_count); line gets executed the duplicate_count is still 0. Even though the alert for a +1 gets executed.
To me it seems like the function updateUserFields is taking longer to execute so it's taking longer to finish before getting to the alert.
Any ideas or suggestions? Thanks!
var duplicate_count = 0
for (var i = 0; i < skill_id.length; i++) {
function updateUserFields(h) {
if(h) {
duplicate_count++;
alert("count +1");
} else {
alert("none found");
}
}
var g = new cfc_mentoring_find_mentor();
g.setCallbackHandler(updateUserFields);
g.is_relationship_duplicate(resource_id, mentee_id, section_id[i], skill_id[i], active_ind,table);
};
alert(duplicate_count);
There is no reason whatsoever to use client-side JavaScript/jQuery to remove duplicates from your database. Security concerns aside (and there are a lot of those), there is a much easier way to make sure the entries in your database are unique: use SQL.
SQL is capable of expressing the requirement that there be no duplicates in a table column, and the database engine will enforce that for you, never letting you insert a duplicate entry in the first place. The syntax varies very slightly by database engine, but whenever you create the table you can specify that a column must be unique.
Let's use SQLite as our example database engine. The relevant part of your problem is right now probably expressed with tables something like this:
CREATE TABLE Person(
id INTEGER PRIMARY KEY ASC,
-- Other fields here
);
CREATE TABLE MentorRelationship(
id INTEGER PRIMARY KEY ASC,
mentorID INTEGER,
menteeID INTEGER,
FOREIGN KEY (mentorID) REFERENCES Person(id),
FOREIGN KEY (menteeID) REFERENCES Person(id)
);
However, you can make enforce uniqueness i.e. require that any (mentorID, menteeID) pair is unique, by changing the pair (mentorID, menteeID) to be the primary key. This works because you are only allowed one copy of each primary key. Then, the MentorRelationship table becomes
CREATE TABLE MentorRelationship(
mentorID INTEGER,
menteeID INTEGER,
PRIMARY KEY (mentorID, menteeID),
FOREIGN KEY (mentorID) REFERENCES Person(id),
FOREIGN KEY (menteeID) REFERENCES Person(id)
);
EDIT: As per the comment, alerting the user to duplicates but not actually removing them
This is still much better with SQL than with JavaScript. When you do this in JavaScript, you read one database row at a time, send it over the network, wait for it to come to your page, process it, throw it away, and then request the next one. With SQL, all the hard work is done by the database engine, and you don't lose time by transferring unnecessary data over the network. Using the first set of table definitions above, you could write
SELECT mentorID, menteeID
FROM MentorRelationship
GROUP BY mentorID, menteeID
HAVING COUNT(*) > 1;
which will return all the (mentorID, menteeID) pairs that occur more than once.
Once you have a query like this working on the server (and are also pulling out all the information you want to show to the user, which is presumably more than just a pair of IDs), you need to send this over the network to the user's web browser. Essentially, on the server side you map a URL to return this information in some convenient form (JSON, XML, etc.), and on the client side you read this information by contacting that URL with an AJAX call (see jQuery's website for some code examples), and then display that information to the user. No need to write in JavaScript what a database engine will execute orders of magnitude faster.
EDIT 2: As per the second comment, checking whether an item is already in the database
Almost everything I said in the first edit applies, except for two changes: the schema and the query. The schema should become the second of the two schemas I posted, since you don't want the database engine to allow duplicates. Also, the query should be simply
SELECT COUNT(*) > 0
FROM MentorRelationship
WHERE mentorID = #mentorID AND menteeID = #menteeID;
where #mentorID and #menteeID are the items that the user selected, and are inserted into the query by a query builder library and not by string concatenation. Then, the server will get a true value if the item is already in the database, and a false value otherwise. The server can send that back to the client via AJAX as before, and the client (that's your JavaScript page) can alert the user if the item is already in the database.

Is there any documentation about how Revision.Description is populated and under what condition?

Is there any documentation about how Revision.Description is populated and under what condition?
I'm writing a Custom Application for Rally so that I can view changes made to Task and HierarchicalRequirement objects via a table with a rolling 7 day period.
The attributes that I'm interested in are:
HierarchicalRequirement
PlanEstimate
TaskEstimateTotal
TaskActualTotal
TaskRemainingTotal
Task
Estimate
ToDo
Actuals
I'm traversing Revisions to get snapshot views of tasks and stories:
It's easy to retrieve these attributes for the current day. However, I need to traverse RevisionHistory -> Revisions and then parse the Revision.Description to apply the differences for Task and HierarchicalRequirement objects. This may provide a daily snapshot of each object.
For example: the following were appended to Revision.Description after took place:
TASK REMAINING TOTAL changed from [7.0] to [4.0]
TASK ESTIMATE TOTAL changed from [7.0] to [4.0]
The "rolling 7 day" period is just an example. My intention is to create a table with a breakdown of Team -> Story -> Task -> Estimate -> ToDo along the y-axis and Iteration -> daily-date along the x-axis.
Tim.
The Revision.description field on many of the Rally object types was not originally intended for developers to get change information but rather for display purposes for our Rally ALM SaaS tool - that's why changes are put in a Revision attribute called 'description' which is just a text field. So there is no developer documentation on the format of this data since it is a text field and not intended to be parsed and the format could change in the future (in the future there will be a better way to get object change information. More on this later in this post...)
However, there is a pattern in this data. It is:
ATTRIBUTE_NAME action VALUE_CLAUSE
The actions are 'added' or 'changed'.
The value clause format is based on the action type. For the 'added' action the value clause is [value]. For the 'changed' action the value clause is 'from [old value] to [new value]'.
For example, for an existing User Story that had an owner set to 'Newt' from 'No Entry', a new revision instance is created the description would have this contained in it:
OWNER added [Newt]
If then later the user changed the owner to 'John', then a new revision will be created that looks like this:
OWNER changed from [Newt] to [John]
If there is more than one attribute change then the changes are separated by commas and there is no guaranteed sorting order of the changes.
Now for the better way to do this in the future. Since you are not the only developer that wants to get at object changes we have a new product under development that will have WSAPI endpoints exposed where you can get changes for an object in a programatic way that should avoid you needing to parse data. But since this product is under development you'll have to do what you are doing now and hopefully my explanation of the format of the data in the description will help you in the meantime.
Hope this helps.
The data you are seeking may also exist in the IterationCumulativeFlowData or ReleaseCumulativeFlowData objects in Rally's WSAPI:
https://rally1.rallydev.com/slm/doc/webservice/
That should be easier (and perform better) than grepping through all the revision history entries.

Related Parameters in HTML

I have a table of rows and columns on an HTML-based entry form that allows the user to edit multiple records. Each row corresponds to a database record and each column to a database field.
When the user submits the form, the server needs to figure out which request parameter belongs to which row. The method I've been using for years is to prefix or suffix each HTML input element's name to indicate the row it belongs to. For example, all input elements would have the suffix "row1" so that the server would know that request parameters whose names end with "row1" are field values for the first row.
While this works, one caveat of the suffix/prefix approach is that you're adding a constraint that you can't name any other elements with a particular suffix/prefix. So I wonder if there's a better, more elegant approach. I'm using JSP for the presentation layer, by the way.
Thanks.
I don't know JSP very well, but in PHP you would define your input fields' names with an array syntax.
<input name='person[]'>
<input name='person[]'>
<input name='person[]'>
When PHP receives a form like that, it gives you an array (within the standard $_POST array), thus:
$_POST['person']=array('alice','bob','charlie');
Which makes it very easy to deal with having as many sets of fields as you want.
You can also explicitly name the array elements:
<input name='person[teamleader]'>
<input name='person[developer1]'>
would give you an array with those keys. If your current prefixes are meaningful beyond simply numbering the records, this would solve that problem.
I don't know whether the identical syntax would work for JSP, but I imagine it would allow something very similar.
Hope that helps.
Current user agents send back the values in the order of the fields as presented to the user.
This means that you could (theoretically) drop the prefix/suffix altogether and sort it out based on the ordering of the values. You'd get something like
/?name=Tom&gender=M&name=Jane&gender=F&name=Roger&gender=M
I don't know how your framework returns that, but many return it as lists of each value
name = [Tom, Jane, Roger]
gender = [M, F, M]
If you pop an element off of each list, you should get a related set that you can work with.
The downside to this is that it relies on a standard behavior which is not actually required by the specification. Still... it's a convenient solution with a behavior that won't be problematic in practice.
When browsers POST that information back to the server, it is just a list of parameters:
?name_row1=Jeff&browser_row1=Chrome&name_row2=Mark&browser_row2=IE8
So really, I think you can answer a simpler question: how do you relate keys in a key-value list?
Alternatively, you can go to a more structured delivery method (JSON or XML), which will automatically give you a structured data format. Of course, this means you'll need to build this value on the browser first, then send it via AJAX (or via the value of a hidden input field) and then unpack/deserialize it in the server code.
XML:
<rows>
<row><id>1</id><name>Jeff</name><browser>Chrome</browser></row>
<row>...</row>
</rows>
or JSON:
[{ "name":"Jeff", "browser":"Chrome"}, { "name":"Mark", "browser":"IE8" }]
There are many resources/tutorials on how to do this... Google it. Or go with the ostensible StackOverflow consensus and try jQuery.

Categories

Resources