{"id":2037,"date":"2015-01-16T11:45:27","date_gmt":"2015-01-16T11:45:27","guid":{"rendered":"http:\/\/www.silkstream.net\/blog\/?p=2037"},"modified":"2016-06-09T10:24:38","modified_gmt":"2016-06-09T10:24:38","slug":"generating-random-post-times-for-hootsuite-csv","status":"publish","type":"post","link":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html","title":{"rendered":"Generating Random Post Times for Hootsuite CSV"},"content":{"rendered":"<h2><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2049\" alt=\"Hootsuite Bulk Scheduling\" src=\"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-scheduler.png\" width=\"556\" height=\"215\" \/><\/h2>\n<h2>Hootsuite&#8217;s Bulk Scheduling<\/h2>\n<p style=\"text-align: justify;\">Hootsuite offers a way to bulk upload social media posts via a CSV (Comma Separated Values) file to schedule posts according to your chosen dates and times. This is an extremely useful feature of Hootsuite that saves loads of time when social media scheduling, as you can just write the dates and times to post each Tweet or post without having to schedule each one manually.<\/p>\n<p style=\"text-align: justify;\">Recently, I&#8217;ve had a client whose company regulations do not permit me direct admin access to their web properties. They just wanted a hand with their social media, which can be challenging when you don&#8217;t have access to their social media accounts. Hootsuite&#8217;s bulk scheduler allows me to schedule their Tweets and Facebook\/Google+\/LinkedIn posts on a monthly basis, and all I have to do is send the client the CSV file each month containing the schedule, for them to approve and edit how they wish. It is then up to the client to upload the CSV file to Hootsuite and engage with their fans and followers appropriately throughout the month.<\/p>\n<p style=\"text-align: justify;\">Unfortunately, I&#8217;ve found that the creation of the social schedule CSV can be a little time-consuming. Which is fine if that time was spent just on the planning and writing of social media posts. But it seemed to me personally as if the most unnecessarily time-consuming aspect of the scheduling was the typing out of dates and coming up with different times to post every day so that it looks more natural. Of course you could choose to post at the exact same time every day but that to me would just scream &#8220;Hello, I&#8217;m automated!&#8221; and look off-putting as a fan or follower.<\/p>\n<p style=\"text-align: justify;\">Bulk scheduling posts across your social media platforms should not be considered a replacement for engaged social media activity. If you think that you can just bulk upload all your Tweets, Facebook status updates and other social network posts and just be done with it, it&#8217;s going to be very obvious that you&#8217;re not there to interact with your fans and followers. Instead, bulk scheduling should be used as a way to put out regular content steadily across all of your social media platforms, whilst engaging with your fans and followers simultaneously. If they comment or reply, you should be quick to respond. They&#8217;ve taken the time to engage with you, and you should take the time to return the gesture. Not only will it make you or your brand easier to relate to, but building and maintaining these relationships with your fans and followers makes the entire social media experience more enjoyable and pleasant for everyone involved. It will also encourage more users to Like or Follow you.<\/p>\n<h2>Creating the Hootsuite CSV Template<\/h2>\n<p style=\"text-align: justify;\">A quick glance at what we&#8217;re going to be programming, before we break down the code in full to see what each bit actually does so that you can adjust the Hootsuite CSV template to your own preferences and bulk scheduling requirements. At the end of this tutorial is a full uncommented example of the following code, that you should be able to just copy and paste straight into IDLE or whatever IDE\/editor of your choosing for you to play around with.<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><code><span style=\"color: #000000; font-size: 12px;\"><span style=\"color: #ff6600;\"># First we import all the modules we need...<\/span><span style=\"color: #000000;\">\r\nimport csv\r\nfrom random import randrange, randint\r\nfrom datetime import date, time\r\nfrom calendar import monthrange, weekday\r\n\r\n<span style=\"color: #ff6600;\"># Set our menu variable to True by default. You'll see why.<\/span>\r\nmenu = True\r\n\r\n<span style=\"color: #ff6600;\"># While our menu is True, keep asking for user input<\/span>\r\nwhile menu:\r\n    <span style=\"color: #ff6600;\"># Ask the user for the number representing their chosen month<\/span>\r\n    month = int(raw_input(\"Which month to schedule for? (e.g. Jan is 1, etc)\"))\r\n    <span style=\"color: #ff6600;\"># If the month number is between 1-12, then proceed with the CSV<\/span>\r\n    if month&gt;0 and month&lt;12:\r\n        <span style=\"color: #ff6600;\"># Create\/Open hootsuite.csv file to write to<\/span>\r\n        open_schedule = open(\"hootsuite.csv\", \"wb\")\r\n        schedule = csv.writer(open_schedule)\r\n        <span style=\"color: #ff6600;\"># For every day of the chosen month, do stuff.<\/span>\r\n        for x in range(0,monthrange(2015,month)[1]):\r\n            <span style=\"color: #ff6600;\"># Unless it's the weekend, then ignore it.<\/span>\r\n            if weekday(2015,month,x+1)==5 or weekday(2015,month,x+1)==6:\r\n                pass\r\n            <\/span><span style=\"color: #ff6600;\"># If it's not the weekend though!<\/span><span style=\"color: #000000;\">\r\n            else:\r\n                <span style=\"color: #ff6600;\"># Assign 3 random post times between these hours<\/span>\r\n                hour1 = randint(9,11)\r\n                hour2 = randint(12,14)\r\n                hour3 = randint(15,16)\r\n                <span style=\"color: #ff6600;\"># Create and format the date<\/span>\r\n                day = date(2015,month,x+1).strftime(\"%d\/%m\/%y\")\r\n                <span style=\"color: #ff6600;\"># Write the date to the CSV followed by the post times<\/span>\r\n                schedule.writerow(\r\n                    [day+\" \"+time(hour1,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n                schedule.writerow(\r\n                    [day+\" \"+time(hour2,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n                schedule.writerow(\r\n                    [day+\" \"+time(hour3,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n        <span style=\"color: #ff6600;\"># Close the Hootsuite CSV file and inform user that it's ready<\/span>\r\n        open_schedule.close()\r\n        print \"hootsuite.csv has been created.\"\r\n        <span style=\"color: #ff6600;\"># Set menu to False to break out of the while loop and exit<\/span>\r\n        menu = False\r\n    <span style=\"color: #ff6600;\"># If month given doesn't exist (isn't 1-12) then help the user<\/span>\r\n    else:\r\n        print \"No month recognised as \"+str(month)\r\n        print \"1.  January\"\r\n        print \"2.  February\"\r\n        print \"3.  March\"\r\n        print \"4.  April\"\r\n        print \"5.  May\"\r\n        print \"6.  June\"\r\n        print \"7.  July\"\r\n        print \"8.  August\"\r\n        print \"9.  September\"\r\n        print \"10. October\"\r\n        print \"11. November\"\r\n        print \"12. December\"\r\n<\/span><\/span><\/code><\/pre>\n<\/div>\n<h2>Breaking Down The Python Code<\/h2>\n<p>So let&#8217;s break it down into pieces&#8230;<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><code><span style=\"color: #000000; font-size: 12px;\"><span style=\"color: #000000;\">import csv\r\nfrom random import randrange, randint\r\nfrom datetime import date, time\r\nfrom calendar import monthrange, weekday<\/span><\/span><\/code><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">You want to import from all of the necessary modules. You can just import <span style=\"color: #ff6600;\"><strong>csv<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>random<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>datetime<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>calendar<\/strong><\/span> but I&#8217;ve chosen to import just <span style=\"color: #ff6600;\"><strong>randrange<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>randint<\/strong><\/span> from <span style=\"color: #ff6600;\"><strong>random<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>date<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>time<\/strong><\/span> from <span style=\"color: #ff6600;\"><strong>datetime<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>monthrange<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>weekday<\/strong><\/span> from <span style=\"color: #ff6600;\"><strong>calendar<\/strong><\/span> &#8211; since I&#8217;m limited on horizontal space for code in this tutorial, it allows me to use things such as <span style=\"color: #ff6600;\"><strong>randint()<\/strong><\/span> without having to include the module name first like\u00a0<span style=\"color: #ff6600;\"><strong>random.randint()<\/strong><\/span>.<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span style=\"color: #000000; font-size: 12px;\"><code>menu = True\r\nwhile menu:<\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">Setting a <span style=\"color: #ff6600;\"><strong>menu<\/strong><\/span> variable to <span style=\"color: #ff6600;\"><strong>True<\/strong><\/span> means that we can use it for a <span style=\"color: #ff6600;\"><strong>while True<\/strong><\/span> loop, that we can later break out of by setting <span style=\"color: #ff6600;\"><strong>menu<\/strong><\/span> to <span style=\"color: #ff6600;\"><strong>False<\/strong><\/span>. This way our menu or schedule options will only continue to display if we have satisfied the program and created the csv file. However if we keep choosing options that aren&#8217;t accepted by the program, it will keep taking us back to the beginning.<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span style=\"color: #000000; font-size: 12px;\"><code>month = int(raw_input(\"Which month to schedule for? (e.g. Jan is 1, etc)\"))\r\nif month&gt;0 and month&lt;12:\r\n    open_schedule = open(\"hootsuite.csv\", \"wb\")\r\n    schedule = csv.writer(open_schedule)<\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">Here we ask the user for input, and name their answer as <strong><span style=\"color: #ff6600;\">month<\/span><\/strong>. We are looking for a number between 1 to 12, 1 representing January and 12 representing December. If they give a number between 1 and 12, the program will continue creating the CSV scheduler in accordance to the chosen month. First the program creates (or opens, should it already exists) a file called hootsuite.csv. You can change the file name to anything you like &#8211; hootsuite.csv, social.csv, twitter.csv, etc&#8230; When we open or create the file, we have to give ourselves permission to write to it and not just read it.<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span style=\"color: #000000; font-size: 12px;\"><code>for x in range(0,monthrange(2015,month)[1]):\r\n    if weekday(2015,month,x+1)==5 or weekday(2015,month,x+1)==6:\r\n        pass<\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">Now we start actually writing to the csv file. We want to go through every single day of our chosen month, and tell our program to do stuff. Using a <span style=\"color: #ff6600;\"><strong>for loop<\/strong><\/span> in Python, we can tell our program to go through every date of the month between 0 and the number of the days within the chosen month. <span style=\"color: #ff6600;\"><strong>monthrange()<\/strong><\/span> can give us this number if we give the parameters of the year and month number (which we&#8217;ve already received from the user input &#8211; <span style=\"color: #ff6600;\"><strong>month<\/strong><\/span>). In this example, I&#8217;ve set the year to 2015. You could make the program ask the user for the year as we did with month, but hard coding 2015 in seems easier for a small program like this, since you&#8217;d only need to change it once a year. Lastly in the <span style=\"color: #ff6600;\"><strong>range<\/strong><\/span> parameters for <span style=\"color: #ff6600;\"><strong>monthrange<\/strong><\/span>, we see the index <span style=\"color: #ff6600;\"><strong>[1]<\/strong><\/span>. This is because <span style=\"color: #ff6600;\"><strong>monthrange<\/strong><\/span> is actually a <span style=\"color: #ff6600;\"><strong>tuple<\/strong><\/span>.<\/p>\n<p style=\"text-align: justify;\">If we typed into the Python Shell:<\/p>\n<p style=\"text-align: justify;\"><strong><span style=\"color: #ff6600;\">&gt;&gt;&gt; from calendar import monthrange<br \/>\n&gt;&gt;&gt; monthrange(2015,1)<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\">it would give us back <span style=\"color: #ff6600;\"><strong>(3, 31)<\/strong><\/span>. We asked monthrange for information about January 2015, and it told us that the first day of January 2015 is a Thursday and that there are 31 days in that month. (Thursday is 3 because Monday is 0 by the way.)<\/p>\n<p style=\"text-align: justify;\">In our for loop, for every day of the month, we want to check whether that day is a Saturday or Sunday. In this particular client&#8217;s industry, they are not worried about maintaining social media activity throughout the weekend since they are targeting other businesses which are likely to only operate on week days. But you can choose to remove these <span style=\"color: #ff6600;\"><strong>if\/else<\/strong><\/span> statements from your program and just schedule for every day if you so wish. Or you can change the days to different days of the week, etc. The <span style=\"color: #ff6600;\"><strong>if<\/strong><\/span> statement is looking out for if <span style=\"color: #ff6600;\"><strong>weekday(2015,month,x+1)<\/strong><\/span> is 5 or 6. Basically, if the date (<span style=\"color: #ff6600;\"><strong>x+1<\/strong><\/span> because x begins at 0) of the chosen month in 2015 is a Saturday or Sunday (5 or 6 &#8211; Monday starts at 0, remember!), then the program will <span style=\"color: #ff6600;\"><strong>pass<\/strong><\/span> on to the next date and not list this date in the CSV.<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span style=\"color: #000000; font-size: 12px;\"><code>else:\r\n    hour1 = randint(9,11)\r\n    hour2 = randint(12,14)\r\n    hour3 = randint(15,16)\r\n    day = date(2015,month,x+1).strftime(\"%d\/%m\/%y\")\r\n    schedule.writerow([day+\" \"+time(hour1,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n    schedule.writerow([day+\" \"+time(hour2,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n    schedule.writerow([day+\" \"+time(hour3,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n<\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">If the day is not a Saturday or Sunday, the program will assign three different integers to three different variables: <span style=\"color: #ff6600;\"><strong>hour1<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>hour2<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>hour3<\/strong><\/span>. This is because I want to schedule three posts a day. <span style=\"color: #ff6600;\"><strong>hour1<\/strong><\/span> will give me a random integer between 9 and 11, <span style=\"color: #ff6600;\"><strong>hour2<\/strong><\/span> between 12 and 14 and <span style=\"color: #ff6600;\"><strong>hour3<\/strong> <\/span>between 15 and 16. If I give <span style=\"color: #ff6600;\"><strong>date()<\/strong><\/span> the parameters of the year as an integer (2015 in this case), the chosen month (which we&#8217;ve conveniently assigned to the\u00a0<span style=\"color: #ff6600;\"><strong>month<\/strong><\/span>\u00a0variable) and the date of the month (<span style=\"color: #ff6600;\"><strong>x+1<\/strong><\/span> because x starts at 0), we can format the date to the string <span style=\"color: #ff6600;\"><strong>&#8220;%d\/%m\/%y&#8221;<\/strong><\/span>. So the 17th September 2015 in that format, for example, would return the string <span style=\"color: #ff6600;\"><strong>&#8220;17\/09\/2015&#8221;<\/strong><\/span>.<\/p>\n<p style=\"text-align: justify;\">Now that we can generate random times between specified hours however many times a day we want, we can write them to our bulk schedule CSV. This is what <span style=\"color: #ff6600;\"><strong>schedule.writerow()<\/strong><\/span> does; we are writing rows to the <span style=\"color: #ff6600;\"><strong>schedule<\/strong><\/span> file. So let&#8217;s take a look at exactly what this is doing:<\/p>\n<p style=\"text-align: center;\"><strong><span style=\"color: #ff6600;\">schedule.writerow([day+&#8221; &#8220;+time(hour1,randrange(0,60,5)).strftime(&#8220;%H:%M&#8221;])<\/span><\/strong><\/p>\n<p style=\"text-align: justify;\">Within each row of the <span style=\"color: #ff6600;\"><strong>schedule<\/strong><\/span> CSV we are concatenating\u00a0<span style=\"color: #ff6600;\"><strong>day\u00a0<\/strong><\/span>(our formatted date) followed by a space and then the formatted time as a string. Like <span style=\"color: #ff6600;\"><strong>date()<\/strong><\/span> which we used to get <span style=\"color: #ff6600;\"><strong>day<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>time()<\/strong><\/span> also takes certain parameters. We can actually give <span style=\"color: #ff6600;\"><strong>time()<\/strong><\/span> the time in hours, minutes, seconds and microseconds. But we only need the hour to publish the social media post (generated by <span style=\"color: #ff6600;\"><strong>hour1<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>hour2<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>hour3<\/strong><\/span>) and minutes. <strong><span style=\"color: #ff6600;\">randrange(0,60,5)<\/span><\/strong> will give us a random number between 0 and 60, followed by the optional step of 5 which means that it will count between 0 to 60 in steps of 5 (e.g. 0, 5, 10, 15&#8230;.). Though the step is an optional parameter for <span style=\"color: #ff6600;\"><strong>randrange()<\/strong><\/span>, the step is necessary for bulk scheduling in Hootsuite as Hootsuite will only accept posting times that end in a 5 or a 0. We then convert this time to string and format it as <span style=\"color: #ff6600;\"><strong>&#8220;%H:%M&#8221;<\/strong> <\/span>so that 1 o&#8217;clock in the afternoon will look like <span style=\"color: #ff6600;\"><strong>&#8220;13:00&#8221;<\/strong><\/span>. Lastly, we want to enclose everything in <strong><span style=\"color: #ff6600;\">[]<\/span><\/strong> for <span style=\"color: #ff6600;\"><strong>writerow()<\/strong><\/span>. This is because <span style=\"color: #ff6600;\"><strong>writerow()<\/strong> <\/span>will only accept a sequence, and strings act like sequences of characters. Without the square brackets, each character of each row will be written to its own column. We only want to fill one column with the posting date and time, so by enclosing it in square brackets we are confining the whole string to a single item of a sequence.<\/p>\n<p style=\"text-align: justify;\">Having three <strong><span style=\"color: #ff6600;\">schedule.writerow()<\/span><\/strong>s like this tells our program that we want to write three posts for every date we iterate through. Remember that we&#8217;re still in the <strong><span style=\"color: #ff6600;\">for<\/span><\/strong> loop! If you wanted to schedule more posts throughout the day, for example, four times a day between 9am and 5pm, we can write an additional <span style=\"color: #ff6600;\"><strong>hour4<\/strong><\/span> variable and change the times of <span style=\"color: #ff6600;\"><strong>hour1<\/strong><\/span>, <span style=\"color: #ff6600;\"><strong>hour2<\/strong><\/span> and <span style=\"color: #ff6600;\"><strong>hour3<\/strong><\/span> to spread the posting times evenly. Then you would just add another <span style=\"color: #ff6600;\"><strong>schedule.writerow()<\/strong><\/span> for <span style=\"color: #ff6600;\"><strong>hour4<\/strong><\/span>. You can bulk schedule a maximum number of 11 posts per day using Hootsuite.<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span style=\"color: #000000; font-size: 12px;\"><code>print \"social.csv has been created.\"\r\nopen_schedule.close()\r\nstart = False<\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">Once the program has iterated through all the dates of the month and written to the CSV file, excluding the weekends, then we come out of the <span style=\"color: #ff6600;\"><strong>for<\/strong><\/span> loop and can inform the user that the file has been created by printing it to the console, and then save and close the file. <span style=\"color: #ff6600;\"><strong>start = False<\/strong><\/span> will break us out of the <span style=\"color: #ff6600;\"><strong>while True<\/strong><\/span> loop, so that the program finishes and the month option won&#8217;t be displayed to us again. Though it might seem weird that the menu has been open this entire time, when the program is actually executed, it would have been less than a second since you gave the input a number. To the user, it would seem immediate.<\/p>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2067\" alt=\"Hootsuite CSV with Python\" src=\"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-csv-python.gif\" width=\"556\" height=\"81\" \/><\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span style=\"color: #000000; font-size: 12px;\"><code>    else:\r\n        print \"No month recognised as \"+str(month)\r\n        print \"1.  January\"\r\n        print \"2.  February\"\r\n        print \"3.  March\"\r\n        print \"4.  April\"\r\n        print \"5.  May\"\r\n        print \"6.  June\"\r\n        print \"7.  July\"\r\n        print \"8.  August\"\r\n        print \"9.  September\"\r\n        print \"10. October\"\r\n        print \"11. November\"\r\n        print \"12. December\"<\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: justify;\">If you remember at the beginning of the program, we told our program to only create the CSV file if the month given by the user is between 1 and 12. So what happens if it&#8217;s not? This is where our <span style=\"color: #ff6600;\"><strong>else<\/strong><\/span> statement comes in. If the number given by the user is less than 1 or more than 12, the program will inform that the month isn&#8217;t recognised and display the acceptable numbers alongside their respective month names. Then the program will loop back to the beginning, as we haven&#8217;t escaped the <strong><span style=\"color: #ff6600;\">while True<\/span><\/strong> statement yet by setting <span style=\"color: #ff6600;\"><strong>menu<\/strong><\/span> to <span style=\"color: #ff6600;\"><strong>False<\/strong><\/span>.<\/p>\n<p style=\"text-align: justify;\">This is what it will look like to the user if they type an unacceptable number, followed by if they type an acceptable number afterwards:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2052\" alt=\"Month Scheduler\" src=\"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/month-scheduler.png\" width=\"518\" height=\"293\" \/><\/p>\n<p>Once the program has been correctly executed, you can find the .csv file in your working directory; the same folder that your Python program is in.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2053\" alt=\"Hootsuite Schedule CSV file\" src=\"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-schedule-csv.jpg\" width=\"556\" height=\"150\" \/><\/p>\n<p style=\"text-align: justify;\">You can then open the CSV in Excel or OpenOffice Calc or any other spreadsheet application of your choice. Below, you can see I&#8217;ve uploaded the file to Google Sheets. Your spreadsheet application may change the format of your dates and times, but this is a very quick fix that doesn&#8217;t take more than a few clicks. Just highlight Column A and Format Number by <span style=\"color: #ff6600;\"><strong>dd\/mm\/yyyy hh:mm<\/strong><\/span> (don&#8217;t forget the space!). This is the exact <em>and only<\/em> format that Hootsuite allows when bulk scheduling, and all times must be at least ten minutes from the upload time, with only one message per time slot.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2055\" alt=\"Number Format in Google Sheets\" src=\"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/number-format-google-sheets.png\" width=\"556\" height=\"359\" \/><\/p>\n<h2>Your Final Python Hootsuite CSV Template Generator!<\/h2>\n<p>It should look a little something like this&#8230;<\/p>\n<div style=\"border: dashed #f79239; padding: 8px; margin-bottom: 20px;\">\n<pre><span><code><span style=\"color: #000000; font-size: 12px;\">import csv\r\nfrom random import randrange, randint\r\nfrom datetime import date, time\r\nfrom calendar import monthrange, weekday\r\n\r\nmenu = True\r\n\r\nwhile menu:\r\n    month = int(raw_input(\"Which month to schedule for? (e.g. Jan is 1, etc)\"))\r\n    if month&gt;0 and month&lt;12:\r\n        open_schedule = open(\"hootsuite.csv\", \"wb\")\r\n        schedule = csv.writer(open_schedule)\r\n        for x in range(0,monthrange(2015,month)[1]):\r\n            if weekday(2015,month,x+1)==5 or weekday(2015,month,x+1)==6:\r\n                pass\r\n            else:\r\n                hour1 = randint(9,11)\r\n                hour2 = randint(12,14)\r\n                hour3 = randint(15,16)\r\n                day = date(2015,month,x+1).strftime(\"%d\/%m\/%y\")\r\n                schedule.writerow(\r\n                    [day+\" \"+time(hour1,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n                schedule.writerow(\r\n                    [day+\" \"+time(hour2,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n                schedule.writerow(\r\n                    [day+\" \"+time(hour3,randrange(0,60,5)).strftime(\"%H:%M\")])\r\n        print \"hootsuite.csv has been created.\"\r\n        open_schedule.close()\r\n        menu = False\r\n    else:\r\n        print \"No month recognised as \"+str(month)\r\n        print \"1.  January\"\r\n        print \"2.  February\"\r\n        print \"3.  March\"\r\n        print \"4.  April\"\r\n        print \"5.  May\"\r\n        print \"6.  June\"\r\n        print \"7.  July\"\r\n        print \"8.  August\"\r\n        print \"9.  September\"\r\n        print \"10. October\"\r\n        print \"11. November\"\r\n        print \"12. December\"\r\n<\/span><\/code><\/span><\/pre>\n<\/div>\n<p style=\"text-align: center;\"><em><strong>You should be able to copy the code above and paste it straight into your IDE\/IDLE.<\/strong><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\nHootsuite&#8217;s Bulk Scheduling<br \/>\nHootsuite offers a way to bulk upload social media posts via a CSV (Comma Separated Values) file to schedule posts according <\/p>\n","protected":false},"author":7,"featured_media":2051,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[108,7],"tags":[],"class_list":["post-2037","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-social-media","category-tutorials"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Generating Random Post Times for Hootsuite CSV | Silkstream<\/title>\n<meta name=\"description\" content=\"A simple Python tutorial for generating random post times into a CSV for Hootsuite&#039;s Bulk Scheduler. You are shown how to adjust the code to suit you.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Generating Random Post Times for Hootsuite CSV | Silkstream\" \/>\n<meta property=\"og:description\" content=\"A simple Python tutorial for generating random post times into a CSV for Hootsuite&#039;s Bulk Scheduler. You are shown how to adjust the code to suit you.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html\" \/>\n<meta property=\"og:site_name\" content=\"Silkstream\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/silkstream\" \/>\n<meta property=\"article:published_time\" content=\"2015-01-16T11:45:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-06-09T10:24:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-uploader.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"120\" \/>\n\t<meta property=\"og:image:height\" content=\"120\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Ria\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@RiaLolwut\" \/>\n<meta name=\"twitter:site\" content=\"@silkstreamnet\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ria\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html\"},\"author\":{\"name\":\"Ria\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/#\\\/schema\\\/person\\\/1516b66b9d6da001d8052655282481b1\"},\"headline\":\"Generating Random Post Times for Hootsuite CSV\",\"datePublished\":\"2015-01-16T11:45:27+00:00\",\"dateModified\":\"2016-06-09T10:24:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html\"},\"wordCount\":2068,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/12\\\/hootsuite-bulk-uploader.jpg\",\"articleSection\":[\"Social Media\",\"Tutorials\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html\",\"url\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html\",\"name\":\"Generating Random Post Times for Hootsuite CSV | Silkstream\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/12\\\/hootsuite-bulk-uploader.jpg\",\"datePublished\":\"2015-01-16T11:45:27+00:00\",\"dateModified\":\"2016-06-09T10:24:38+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/#\\\/schema\\\/person\\\/1516b66b9d6da001d8052655282481b1\"},\"description\":\"A simple Python tutorial for generating random post times into a CSV for Hootsuite's Bulk Scheduler. You are shown how to adjust the code to suit you.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#primaryimage\",\"url\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/12\\\/hootsuite-bulk-uploader.jpg\",\"contentUrl\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/12\\\/hootsuite-bulk-uploader.jpg\",\"width\":120,\"height\":120},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/2015\\\/01\\\/generating-random-post-times-for-hootsuite-csv.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.silkstream.net\\\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Generating Random Post Times for Hootsuite CSV\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/\",\"name\":\"Silkstream\",\"description\":\"Here you&#039;ll find the latest blogs, white papers and case studies from Silkstream experts.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.silkstream.net\\\/blog\\\/#\\\/schema\\\/person\\\/1516b66b9d6da001d8052655282481b1\",\"name\":\"Ria\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dad9acd650d88d7fd9c7e2b77f38d25ec2c921eb7efb622d785820719d8a75df?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dad9acd650d88d7fd9c7e2b77f38d25ec2c921eb7efb622d785820719d8a75df?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/dad9acd650d88d7fd9c7e2b77f38d25ec2c921eb7efb622d785820719d8a75df?s=96&d=mm&r=g\",\"caption\":\"Ria\"},\"description\":\"SEO &amp; Internet Marketing addict, and aspiring crazy cat lady.\",\"sameAs\":[\"http:\\\/\\\/www.silkstream.net\",\"https:\\\/\\\/x.com\\\/RiaLolwut\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Generating Random Post Times for Hootsuite CSV | Silkstream","description":"A simple Python tutorial for generating random post times into a CSV for Hootsuite's Bulk Scheduler. You are shown how to adjust the code to suit you.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html","og_locale":"en_GB","og_type":"article","og_title":"Generating Random Post Times for Hootsuite CSV | Silkstream","og_description":"A simple Python tutorial for generating random post times into a CSV for Hootsuite's Bulk Scheduler. You are shown how to adjust the code to suit you.","og_url":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html","og_site_name":"Silkstream","article_publisher":"https:\/\/www.facebook.com\/silkstream","article_published_time":"2015-01-16T11:45:27+00:00","article_modified_time":"2016-06-09T10:24:38+00:00","og_image":[{"width":120,"height":120,"url":"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-uploader.jpg","type":"image\/jpeg"}],"author":"Ria","twitter_card":"summary_large_image","twitter_creator":"@RiaLolwut","twitter_site":"@silkstreamnet","twitter_misc":{"Written by":"Ria","Estimated reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#article","isPartOf":{"@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html"},"author":{"name":"Ria","@id":"https:\/\/www.silkstream.net\/blog\/#\/schema\/person\/1516b66b9d6da001d8052655282481b1"},"headline":"Generating Random Post Times for Hootsuite CSV","datePublished":"2015-01-16T11:45:27+00:00","dateModified":"2016-06-09T10:24:38+00:00","mainEntityOfPage":{"@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html"},"wordCount":2068,"commentCount":0,"image":{"@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#primaryimage"},"thumbnailUrl":"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-uploader.jpg","articleSection":["Social Media","Tutorials"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html","url":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html","name":"Generating Random Post Times for Hootsuite CSV | Silkstream","isPartOf":{"@id":"https:\/\/www.silkstream.net\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#primaryimage"},"image":{"@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#primaryimage"},"thumbnailUrl":"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-uploader.jpg","datePublished":"2015-01-16T11:45:27+00:00","dateModified":"2016-06-09T10:24:38+00:00","author":{"@id":"https:\/\/www.silkstream.net\/blog\/#\/schema\/person\/1516b66b9d6da001d8052655282481b1"},"description":"A simple Python tutorial for generating random post times into a CSV for Hootsuite's Bulk Scheduler. You are shown how to adjust the code to suit you.","breadcrumb":{"@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#primaryimage","url":"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-uploader.jpg","contentUrl":"https:\/\/www.silkstream.net\/blog\/wp-content\/uploads\/2014\/12\/hootsuite-bulk-uploader.jpg","width":120,"height":120},{"@type":"BreadcrumbList","@id":"https:\/\/www.silkstream.net\/blog\/2015\/01\/generating-random-post-times-for-hootsuite-csv.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.silkstream.net\/blog"},{"@type":"ListItem","position":2,"name":"Generating Random Post Times for Hootsuite CSV"}]},{"@type":"WebSite","@id":"https:\/\/www.silkstream.net\/blog\/#website","url":"https:\/\/www.silkstream.net\/blog\/","name":"Silkstream","description":"Here you&#039;ll find the latest blogs, white papers and case studies from Silkstream experts.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.silkstream.net\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/www.silkstream.net\/blog\/#\/schema\/person\/1516b66b9d6da001d8052655282481b1","name":"Ria","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/dad9acd650d88d7fd9c7e2b77f38d25ec2c921eb7efb622d785820719d8a75df?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/dad9acd650d88d7fd9c7e2b77f38d25ec2c921eb7efb622d785820719d8a75df?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dad9acd650d88d7fd9c7e2b77f38d25ec2c921eb7efb622d785820719d8a75df?s=96&d=mm&r=g","caption":"Ria"},"description":"SEO &amp; Internet Marketing addict, and aspiring crazy cat lady.","sameAs":["http:\/\/www.silkstream.net","https:\/\/x.com\/RiaLolwut"]}]}},"_links":{"self":[{"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/posts\/2037","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/comments?post=2037"}],"version-history":[{"count":23,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/posts\/2037\/revisions"}],"predecessor-version":[{"id":2109,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/posts\/2037\/revisions\/2109"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/media\/2051"}],"wp:attachment":[{"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/media?parent=2037"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/categories?post=2037"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silkstream.net\/blog\/wp-json\/wp\/v2\/tags?post=2037"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}