Introduction
I built a web crawler for a project. One of the variables parse from the website is the date. I thought that building a dictionary containing the month in French and the int associated with it.
The way that I saw the code going is.
Scrape the data from the website
var moisLettres
Find the variable in the dictionary
Return the number associated with it
So far, I built this code, I searched for a few hours but the concept of comparing a dictionary is a little bit confusing. I'm open to other solutions since I'm here to help. Feel free to correct me.
Dictionary:
IDictionary<string, int> dictMonth = new Dictionary<string, int>();
dictMonth.Add("Janvier",1);
dictMonth.Add("Février",2);
dictMonth.Add("Mars",3);
//Up to 12 months
Examples so far:
foreach (KeyValuePair<string, int> b in dictMonth) //
{
if (b.Value.Equals(e.MonthInLetters, StringComparison.CurrentCultureIgnoreCase))
return /* The TValue associated */
}
Ways I explored:
Using the date.time method to translate automatically the month in string to month in Int. Since the data scraped is in French, the code doesn't work.
FULL CODE 1/2 (Some variables are in French since it is my main language)
`
{
//Variables de bases
const string accountSid = "Private";
const string authToken = "Private";
List<Date> lstDate = new List<Date>();
string sMessage = "";
//Création du dictionnaire
IDictionary<string, int> dictMois = new Dictionary<string, int>();
dictMois.Add("Janvier",1);
dictMois.Add("Février",2);
dictMois.Add("Mars",3);
dictMois.Add("Avril",4);
dictMois.Add("Mai",5);
dictMois.Add("Juin",6);
dictMois.Add("Juillet",7);
dictMois.Add("Aout",8);
dictMois.Add("Septembre",9);
dictMois.Add("Octobre",10);
dictMois.Add("Novembre",11);
dictMois.Add("Décembre",12);
// Initialisation
Date un = new Date("19 Septembre", "Inconnu", "----------- ");
Date deux = new Date("26 Septembre", "Inconnu", "----------");
Date trois = new Date("3 Octobre", "Inconnu", "-----------");
Date quatre = new Date("10 Octobre", "Inconnu", "-----------");
Date cinq = new Date("17 Octobre", "Inconu", "-----------");
Date six = new Date("24 Octobre", "Inconnu", "-----------");
lstDate.Add(un);
lstDate.Add(deux);
lstDate.Add(trois);
lstDate.Add(quatre);
lstDate.Add(cinq);
lstDate.Add(six);
//Captation des dates
foreach (Date d in lstDate)
{
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(d.url);
var xpathDate = "-----------";
var locationDate = doc.DocumentNode.SelectSingleNode(xpathDate);
var dateEvenement = locationDate.InnerText;
d.date = dateEvenement;
}
//Vérification si les données sont exactes.
foreach (Date e in lstDate)
{
The way it works
// The data parse is "jeu., 19 septembre 2019"
//un.date = "jeu., 19 septembre 2019"
// un.annee = "jeu., 19 septembre 2019"
// un.annee = (un.date).Substring(un.date.Length -4)
// un.jourMois = "jeu., 19 septembre 2019"
// un.jourMois = (un.date).Subtring(un.date.Length xxx)
//un.moisMots = "jeu., 19 septembre 2019"
//un.moisMots = (un.date).Subtring(un.date.Length xxx)
//un.moisChiffre = (** Here goes the comparaison to the dictionary **)
// At Last
//e.dateReel = (The combinaison of the int of the year, month et day of the month)
//e.dateReel = (e.annee + e.jourMois + e.moisChiffre);
}
//Checking the status of the event if there place it send me a sms message
foreach (Date d in lstDate)
{
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(d.url);
var xpathStatut = "//*[#id='event-page']/main/div[1]/div[2]/div/div[2]/div[2]/div/div[2]/div/div/div";
var locationStatut = doc.DocumentNode.SelectSingleNode(xpathStatut);
var statut = locationStatut.InnerText;
if (statut.IndexOf("Complet") <= 0)
{
if (sMessage == "")
sMessage = "Il reste de la place pour";
sMessage += d.date + " ";
}
}
if (sMessage.Length > 0)
{
TwilioClient.Init(accountSid, authToken);
var message = MessageResource.Create(
body: sMessage,
from: new Twilio.Types.PhoneNumber("-------"),
to: new Twilio.Types.PhoneNumber("------------")
);
Console.WriteLine("Message envoyé" + message.Sid);
}
Console.ReadKey();
FULL CODE 2/2 - Classe Date:
class Date
{
public string date;
public string statut;
public string url;
public string moisMots;
public int moisChiffre;
public string jourMois;
public string annee;
public string dateReel;
public Date(string Date, string Statut, string Url)
{
date = Date;
statut = Statut;
url = Url;
}
}
To get the month from a string, DateTime.Parse can be used :
var culture = new System.Globalization.CultureInfo("fr");
var date = DateTime.Parse("jeu., 19 septembre 2019", culture);
int year = date.Year, month = date.Month, day = date.Day; // 2019, 9, 19
For more reliable code, DateTime.TryParse and DateTime.TryParseExact can be used.
It looks like you're looking for a way to lookup a value in a dictionary from a key. You can use the dictionary[key] syntax:
IDictionary<string, int> dictMonth = new Dictionary<string, int>();
dictMonth.Add("Janvier", 1);
dictMonth.Add("Février", 2);
dictMonth.Add("Mars", 3);
string myMonth = "Février"; //comes from your parsed data, for example.
int monthNumber = dictMonth[myMonth]; //lookup value in dictionary
//monthNumber is now equal to 2
You should check that that the key you're looking for exists in the dictionary by using the ContainsKey method, otherwise dictMonth[myMonth] will throw an exception if myMonth is not in dictMonth.
Related
Hi i have the following code, the problem i am facing is no matter if the folder exists it still continues to send the email instead of ignoring to send it.
What can i change to get this working.
static void Main(string[] args)
{
string yesterdaydate = DateTime.Now.AddDays(-1).ToString("yyyy-mm-dd");
string[] SplitDate = yesterdaydate.Split('-');
string year = SplitDate[0];
string month = SplitDate[1];
string day = SplitDate[2];
string path = Path.Combine("C:\\Users\\ales\\Desktop\\test", year, month, day);
if (Directory.Exists(path))
{
//do nothing
}
else
{
string fromAddress = "noreply#arm.com";
string toAddress = "alese#arm.com";
string subject = "error";
string body = "failed to sync";
krysalis_email.EmailClient email = new krysalis_email.EmailClient();
krysalis_email.EmailClient.EmailResponse emailResponse = email.sendBasicMail(new object[] {toAddress}, fromAddress, subject, body, false, "smtp.za.arm.com",
new string[] {"", ""}, false, null);
if (emailResponse != null)
{
}
}
}
The problem is in your date format to string. You are using mm which is minutes. Use MM to get month. Keep in mind that MM format will give you month with leading zero, for example 08
If you want to use string splitting, then change the code to
string yesterdaydate = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
But as others pointing, the better way to get values is to use DateTime instead of parsing string. Here is an example:
DateTime yesterdaydate = DateTime.Now.AddDays(-1);
string year = yesterdaydate.Year.ToString();
string month = yesterdaydate.Month.ToString("D2");//D2 to format number to be zero-padded
string day = yesterdaydate.Day.ToString("D2");
string path = Path.Combine("C:\\Users\\ales\\Desktop\\test", year, month, day);
Exception while executing Stanford NLP through visual studio :
Package : stanford-corenlp-full-2016-10-31 An unhandled exception of
type 'edu.stanford.nlp.io.RuntimeIOException' occurred in
stanford-corenlp-3.9.1.dll
Code:
namespace Stanford.NLP.SUTime.CSharp
{
class Program
{
private static void Main()
{
// Path to the folder with models extracted from `stanford-corenlp-3.7.0-models.jar`
var jarRoot = #"C:\Users\Tharmarajan.s\Desktop\stanford-corenlp-full-2016-10-31\stanford-corenlp-full-2016-10-31\models";
var modelsDirectory = jarRoot + #"\edu\stanford\nlp\models\";
// Annotation pipeline configuration
var pipeline = new AnnotationPipeline();
pipeline.addAnnotator(new TokenizerAnnotator(false));
pipeline.addAnnotator(new WordsToSentencesAnnotator(false));
// Loading POS Tagger and including them into pipeline
var tagger = new MaxentTagger(modelsDirectory +#"\pos-tagger\english-left3words\english-left3words-distsim.tagger");
pipeline.addAnnotator(new POSTaggerAnnotator(tagger));
// SUTime configuration
var sutimeRules = modelsDirectory + #"\sutime\defs.sutime.txt,"
+ modelsDirectory + #"\sutime\english.holidays.sutime.txt,"
+ modelsDirectory + #"\sutime\english.sutime.txt";
var props = new Properties();
props.setProperty("sutime.rules", sutimeRules);
props.setProperty("sutime.binders", "0");
pipeline.addAnnotator(new TimeAnnotator("sutime", props));
// Sample text for time expression extraction
var text = "Three interesting dates are 18 Feb 1997, the 20th of july and 4 days from today.";
var annotation = new Annotation(text);
annotation.set(new CoreAnnotations.DocDateAnnotation().getClass(), "2013-07-14");
pipeline.annotate(annotation);
Console.WriteLine("{0}\n", annotation.get(new CoreAnnotations.TextAnnotation().getClass()));
var timexAnnsAll = annotation.get(new TimeAnnotations.TimexAnnotations().getClass()) as ArrayList;
foreach (CoreMap cm in timexAnnsAll)
{
var tokens = cm.get(new CoreAnnotations.TokensAnnotation().getClass()) as List;
var first = tokens.get(0);
var last = tokens.get(tokens.size() - 1);
var time = cm.get(new TimeExpression.Annotation().getClass()) as TimeExpression;
Console.WriteLine("{0} [from char offset {1} to {2}] --> {3}",
cm, first, last, time.getTemporal());
}
}
}
}
i have 'created date' and 'closed date' in my file and i'm converting it in json so i have that dates in json.
in my method i have two parameter like from date and to date and i want to count particular column data of my file between from date and to date.so how can we write code to fetch it using linq.
i tried this...
public JsonResult StatusDerails(DateTime from,DateTime to)
{
string csvurl = WebConfigurationManager.AppSettings["csvfileurl"];
var lines = System.IO.File.ReadAllLines(csvurl).Skip(1);
List<Product> prdt = new List<Product>();
foreach (string line in lines)
{
Product c1 = new Product();
var split = line.Split(',');
c1.ID = Int32.Parse(split[0]);
c1.Area_Path = split[1];
c1.IterationPath = split[2];
c1.State = split[3];
c1.Reason = split[4];
c1.Priority = Int32.Parse(split[5]);
c1.Severity = split[6];
c1.Tags = split[7];
c1.Title = split[8];
c1.CreatedDate = split[9];
c1.CreatedBy = split[10];
c1.ResolvedDate = split[11];
c1.ResolvedBy = split[12];
c1.ClosedDate = split[13];
c1.AssignedTo = split[14];
prdt.Add(c1);
}
//var list = prdt.GroupBy(a=>a.AreaPath).Select(a=>new UIproduct() {
var productName = prdt.Select(a => a.Area_Path).Distinct();
List<StatusDetail> statusdetail = new List<StatusDetail>();
foreach (var Name in productName)
{
StatusDetail sd = new StatusDetail();
sd.CarryOver = prdt.Where(a => a.CreatedDate >= from.Date.ToString() && a.ClosedDate <= to.Date.ToShortDateString
}
return Json(statusdetail, JsonRequestBehavior.AllowGet);
}
The comparison of DateTime as string will not be a good option and that wont gives you the exact result, So I recommend you to change the type of CreatedDate and ClosedDate to DateTime. and compare two DateTime values in linq. I think instead of splitting json for creating object of certain types you can use json converters.
Fix for your scenario:
c1.CreatedDate = DateTime.Parse(split[9]);
c1.ClosedDate = DateTime.Parse(split[13]);
Don't forget to change the type in the class, Now its fine to use the linq as like the following:
sd.CarryOver = prdt.Where(a => a.CreatedDate >= from.Date && a.ClosedDate <= to.Date);
I am new to c# . When i am trying to import excel sheet using the following code :
try
{
DateTime date = DateTime.FromOADate(w.Cells[i, index[j]].value2);
string str = date.ToString("d-M-yyyy");
dRow[j] = Convert.ToDateTime(str, ci);
}
catch (Exception)
{
try
{
String ss1 = (String)w.Cells[i, index[j]].value2;
if (ss1 == null || ss1.Equals("NIL") || ss1.Equals("."))
{
dRow[j] = DBNull.Value;
}
else if (ss1 != null)
{
DateTime dat = Convert.ToDateTime(ss1);
ss1 = dat.ToString(ci.NumberFormat);
dRow[j] = Convert.ToDateTime(ss1,null);
}
else
{
dRow[j] = DBNull.Value;
}
}
catch (Exception ex1)
{
try
{
String ss2 = (String)w.Cells[i, index[j]].value2;
if (ss2 != null)
{
String ss2_t = ss2.Trim();
DateTime da = DateTime.ParseExact(ss2_t, "d-M-yyyy", null);
dRow[j] = da;
}
else
{
dRow[j] = DBNull.Value;
}
}
catch (Exception ex2)
{
try
{
String ss3 = (String)w.Cells[i, index[j]].value2;
if (ss3 != null)
{
String ss3_t = ss3.Trim();
DateTime da1 = DateTime.ParseExact(ss3, "d-M-yyyy", CultureInfo.InvariantCulture);
dRow[j] = da1;
}
else
{
dRow[j] = DBNull.Value;
}
}
catch (Exception)
{
dRow[j] = DBNull.Value;
}
}
}
Everything works fine untill date has day value less than 12. For example if DATE is 23-07-2013 it works fine . but if DATE is 7-5-2013 then DateTime.FromOADate() convert it into 5-July-2013 . I am totally stuck. Please help me as soon as possible.
If you mean the difficulty is with your str variable then use this format:
string str = date.ToString("dd-mm-yyyy");
Update
The argument passed to DateTime.FromOADate() is a double which is obviously not format sensitive. So I'm not exactly sure why you'd need to convert it to a string and then back to a date. Is it possible that dRow[j] = date is all you need?
If the returned valued of FromOADate() is incorrect then you need to return to your source data, ie Excel. You would need to adjust the format settings there or, if that data was imported, run a small VBA macro to convert the values yourself.
I'm not sure where in the code you are seeing the "d-M-yyyy" v. "M-d-yyy" difference. If you are looking at your dRow[j] variable then this will abide by your defined CultureInfo, presumably the ci variable.
Below is some code that shows three ways of managing date string conversions, the first two manipulate the CultureInfo, the third is pure manual string parsing.
Have a play to see if any of these suit your needs, but I still return to my original question of "do you need to go 'date - string - date' at all"?
DateTime date = DateTime.FromOADate(42491);
string str = date.ToString("d-M-yyyy");
Console.WriteLine(str);
//CultureInfos
CultureInfo ciGB = new CultureInfo("en-GB", false);
CultureInfo ciUS = new CultureInfo("en-US", false);
//ToDateTime version
DateTime dateGB = Convert.ToDateTime(str, ciGB);
DateTime dateUS = Convert.ToDateTime(str, ciUS);
Console.WriteLine("ToDateTime: GB = {0}, US = {1}", dateGB, dateUS);
//ParseExact version
DateTime parsedGB = DateTime.ParseExact(str,"d-M-yyyy", ciGB);
DateTime parsedUS = DateTime.ParseExact(str, "M-d-yyyy", ciUS);
Console.WriteLine("ParseExact: GB = {0}, US = {1}", parsedGB, parsedUS);
//Manual parsing
var parts = str.Split('-');
int item1 = int.Parse(parts[0]);
int item2 = int.Parse(parts[1]);
int item3 = int.Parse(parts[2]);
DateTime manualGB = new DateTime(item3, item2, item1);
DateTime manualUS = new DateTime(item3, item1, item2);
Console.WriteLine("Manual: GB = {0}, US = {1}", manualGB, manualUS);
I run into a little common problem with datetime class that I have no idea how to resolve.
I don't know what the error is but I see the troubleshooting tips are displayed as
When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object. Make sure your method arguments are in the right format.
Here is the piece of code I extract from my program,
public IEnumerable<CONTACT_INFO> GetContactInfo(string tableName)
{
DataTable dt = GetUserInfo(tableName);
List<CONTACT_INFO> lst = new List<CONTACT_INFO>();
foreach (DataRow row in dt.Rows)
{
string sDate = "";
if(!string.IsNullOrEmpty(row["birthday"].ToString()))
{
sDate = row["birthday"].ToString();
}
string format = "yyyyMMdd";
System.Globalization.CultureInfo provider =CultureInfo.InvariantCulture;
string datetime = DateTime.Now.ToShortDateString();
if (!string.IsNullOrEmpty(sDate))
{
datetime = DateTime.ParseExact(sDate, format, provider).ToShortDateString();
}
if (row["companyname"].ToString().CompareTo("companylogo") != 0)
{
string profile_time = row["profile_timestamp"].ToString();
if (!string.IsNullOrEmpty(profile_time))
{
CSTimeZone time = new CSTimeZone();
profile_time = time.FromUnix(Convert.ToDouble(profile_time)).ToShortDateString()+" "+
time.FromUnix(Convert.ToDouble(profile_time)).ToLongTimeString();
}
string lastUseNetTime = row["last_used_networktime"].ToString();
if (!string.IsNullOrEmpty(lastUseNetTime))
{
CSTimeZone time = new CSTimeZone();
double sec = Convert.ToDouble(lastUseNetTime) * 60;
lastUseNetTime = time.FromUnix(Convert.ToDouble(sec)).ToShortDateString() + " " +
time.FromUnix(Convert.ToDouble(sec)).ToLongTimeString();
}
string lastOnlineTime = row["lastonline_timestamp"].ToString();
if (!string.IsNullOrEmpty(lastOnlineTime))
{
CSTimeZone time = new CSTimeZone();
lastOnlineTime = time.FromUnix(Convert.ToDouble(lastOnlineTime)).ToShortDateString() + " " +
time.FromUnix(Convert.ToDouble(lastOnlineTime)).ToLongTimeString();
}
lst.Add(new CONTACT_INFO()
{
gender=Convert.ToInt32(row["gender"].ToString()),
timezone=row["timezone"].ToString(),
fullName = row["fullname"].ToString(),
profile_timestamp = profile_time,
last_used_networktime = lastUseNetTime,
lastonline_timestamp = lastOnlineTime,
birthday = string.IsNullOrEmpty(sDate) ? "" : datetime
});
}
}
return lst;
}
The function FromUnix is written as
public DateTime FromUnix(double seconds)
{
DateTime datetime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime();
return datetime.AddSeconds(seconds);
}
I am pretty sure this is a parsing problem
The following line would throw exceptions if the value of sDate is not in the defined format of yyyyMMdd
datetime = DateTime.ParseExact(sDate, format, provider).ToShortDateString();
I would first use TryParseExact instead of a simple Parse since you do not seem to be using try/catch clauses. It might be a good idea to use the debugger to see exactly where your program is failing.
Other example of potential failures in your code are
double sec = Convert.ToDouble(lastUseNetTime) * 60;
Use double.tryParse
Convert.ToInt32(row["gender"].ToString()
If gender turns out not to be a number another exception will be thrown
etc...